diff --git a/.gitignore b/.gitignore index a9c1d4c..3c55075 100644 --- a/.gitignore +++ b/.gitignore @@ -1,70 +1,2 @@ -# Uncomment these types if you want even more clean repository. But be careful. -# It can make harm to an existing project source. Read explanations below. -# -# Resource files are binaries containing manifest, project icon and version info. -# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. -*.res -# -# Type library file (binary). In old Delphi versions it should be stored. -# Since Delphi 2009 it is produced from .ridl file and can safely be ignored. -*.tlb -# -# Diagram Portfolio file. Used by the diagram editor up to Delphi 7. -# Uncomment this if you are not using diagrams or use newer Delphi version. -*.ddp -# -# Visual LiveBindings file. Added in Delphi XE2. -# Uncomment this if you are not using LiveBindings Designer. -*.vlb -# -# Deployment Manager configuration file for your project. Added in Delphi XE2. -# Uncomment this if it is not mobile development and you do not use remote debug feature. -*.deployproj -# -# C++ object files produced when C/C++ Output file generation is configured. -# Uncomment this if you are not using external objects (zlib library for example). -*.obj -# - -# Delphi compiler-generated binaries (safe to delete) -*.exe -*.dll -*.bpl -*.bpi -*.dcp -*.so -*.apk -*.drc -*.map -*.dres -*.rsm -*.tds -*.dcu -*.lib -*.a -*.o -*.ocx - -# Delphi autogenerated files (duplicated info) -*.cfg -*.hpp -*Resource.rc - -# Delphi local files (user-specific info) -*.local -*.identcache -*.projdata -*.tvsconfig -*.dsk - -# Delphi history and backups -__history/ -__recovery/ -__astcache/ *.~* - -# Castalia statistics file (since XE7 Castalia is distributed with Delphi) -*.stat - -# Exclude this folders -!Dll/* \ No newline at end of file +*.ddp diff --git a/AboutDlg.cpp b/AboutDlg.cpp new file mode 100644 index 0000000..1327332 --- /dev/null +++ b/AboutDlg.cpp @@ -0,0 +1,22 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "AboutDlg.h" +#include "Misc.h" +extern String IDRVersion; +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +TFAboutDlg_11011981 *FAboutDlg_11011981; +//--------------------------------------------------------------------- +__fastcall TFAboutDlg_11011981::TFAboutDlg_11011981(TComponent* AOwner) + : TForm(AOwner) +{ +} +//--------------------------------------------------------------------- +void __fastcall TFAboutDlg_11011981::FormCreate(TObject *Sender) +{ + lVer->Caption = "Version: " + IDRVersion; + ScaleForm(this); +} +//--------------------------------------------------------------------------- diff --git a/Sources/Forms/AboutDlg.dfm b/AboutDlg.dfm similarity index 96% rename from Sources/Forms/AboutDlg.dfm rename to AboutDlg.dfm index d87f076..f544bfd 100644 Binary files a/Sources/Forms/AboutDlg.dfm and b/AboutDlg.dfm differ diff --git a/AboutDlg.h b/AboutDlg.h new file mode 100644 index 0000000..7df733b --- /dev/null +++ b/AboutDlg.h @@ -0,0 +1,51 @@ +//---------------------------------------------------------------------------- +#ifndef AboutDlgH +#define AboutDlgH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TFAboutDlg_11011981 : public TForm +{ +__published: + TPanel *Panel3; + TButton *Button2; + TPageControl *PageControl1; + TTabSheet *tsIDR; + TTabSheet *tsCrypto; + TImage *Icon; + TLabel *lProduct; + TShape *Shape1; + TShape *Shape2; + TLabel *lVer; + TLabel *lEmail; + TLabel *lWWW; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TLabel *Label5; + TLabel *Label6; + TImage *Image1; + TLabel *Label7; + TLabel *Label8; + TLabel *lblHint; + void __fastcall FormCreate(TObject *Sender); +private: +public: + virtual __fastcall TFAboutDlg_11011981(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFAboutDlg_11011981 *FAboutDlg_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/ActiveProcesses.cpp b/ActiveProcesses.cpp new file mode 100644 index 0000000..b28f705 --- /dev/null +++ b/ActiveProcesses.cpp @@ -0,0 +1,466 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include +#include "Main.h" +#include "ActiveProcesses.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" + +TFActiveProcesses *FActiveProcesses; +//--------------------------------------------------------------------------- +__fastcall TFActiveProcesses::TFActiveProcesses(TComponent* Owner) + : TForm(Owner) +{ + InstPSAPI = 0; + lpEnumProcesses = 0; + lpEnumProcessModules = 0; + + InstKernel32 = 0; + lpCreateToolhelp32Snapshot = 0; + lpProcess32First = 0; + lpProcess32Next = 0; + lpModule32First = 0; + lpModule32Next = 0; + + //Load PSAPI + if (IsWindows2000OrHigher()) + { + //Supported starting from Windows XP/Server 2003 + InstPSAPI = LoadLibrary("PSAPI.DLL"); + if (InstPSAPI) + { + lpEnumProcesses = (TEnumProcesses)GetProcAddress(InstPSAPI, "EnumProcesses"); + lpEnumProcessModules = (TEnumProcessModules)GetProcAddress(InstPSAPI, "EnumProcessModules"); + lpGetModuleFileNameEx = (TGetModuleFileNameEx)GetProcAddress(InstPSAPI, "GetModuleFileNameExA"); + lpGetModuleInformation = (TGetModuleInformation)GetProcAddress(InstPSAPI, "GetModuleInformation"); + } + } + else + { + InstKernel32 = LoadLibrary("kernel32.dll"); + if (InstKernel32) + { + lpCreateToolhelp32Snapshot = (TCreateToolhelp32Snapshot)GetProcAddress(InstKernel32, "CreateToolhelp32Snapshot"); + lpProcess32First = (TProcess32First)GetProcAddress(InstKernel32, "Process32First"); + lpProcess32Next = (TProcess32Next)GetProcAddress(InstKernel32, "Process32Next"); + lpModule32First = (TModule32First)GetProcAddress(InstKernel32, "Module32First"); + lpModule32Next = (TModule32Next)GetProcAddress(InstKernel32, "Module32Next"); + } + } +} +//--------------------------------------------------------------------------- +__fastcall TFActiveProcesses::~TFActiveProcesses() +{ + if (InstPSAPI) FreeLibrary(InstPSAPI); + if (InstKernel32) FreeLibrary(InstKernel32); +} +//--------------------------------------------------------------------------- +void TFActiveProcesses::ShowProcesses95() +{ + HANDLE _hSnapshot, _hSnapshotM; + TListItem *_li; + PROCESSENTRY32 _ppe = {0}; + MODULEENTRY32 _pme = {0}; + + lvProcesses->Items->BeginUpdate(); + lvProcesses->Clear(); + + _hSnapshot = lpCreateToolhelp32Snapshot(TH32CS_SNAPALL, GetCurrentProcessId()); + if (_hSnapshot != INVALID_HANDLE_VALUE) + { + _ppe.dwSize = sizeof(PROCESSENTRY32); + _pme.dwSize = sizeof(MODULEENTRY32); + lpProcess32First(_hSnapshot, &_ppe); + do + { + _hSnapshotM = lpCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, _ppe.th32ProcessID); + if (_hSnapshotM == INVALID_HANDLE_VALUE) + continue; + + if (lpModule32First(_hSnapshotM, &_pme)) + { + _li = lvProcesses->Items->Add(); + _li->Caption = IntToHex((int)_ppe.th32ProcessID, 4); + _li->SubItems->Add(ExtractFileName(String(_ppe.szExeFile))); + _li->SubItems->Add(IntToHex((int)_pme.modBaseSize, 8)); + _li->SubItems->Add("-"); + _li->SubItems->Add(IntToHex((int)_pme.modBaseAddr, 8)); + } + CloseHandle(_hSnapshotM); + } + while (lpProcess32Next(_hSnapshot, &_ppe)); + + CloseHandle(_hSnapshot); + } + lvProcesses->Items->EndUpdate(); +} +//--------------------------------------------------------------------------- +bool TFActiveProcesses::IsWindows2000OrHigher() +{ + OSVERSIONINFO osvi = {0}; + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + //https://msdn.microsoft.com/en-us/library/windows/desktop/ms724834%28v=vs.85%29.aspx + return (osvi.dwMajorVersion >= 5); //win XP+ +} +//--------------------------------------------------------------------------- +void TFActiveProcesses::ShowProcesses() +{ + if (!IsWindows2000OrHigher()) + FActiveProcesses->ShowProcesses95(); + else + FActiveProcesses->ShowProcessesNT(); +} +//--------------------------------------------------------------------------- +void TFActiveProcesses::ShowProcessesNT() +{ + int n, _len, _pos; + String _moduleName; + TListItem *_li; + HANDLE _hProcess; + MODULEINFO _moduleInfo; + char _buf[512]; + + lpEnumProcesses(ProcessIds, sizeof(ProcessIds), &ProcessesNum); + ProcessesNum /= sizeof(ProcessIds[0]); + + lvProcesses->Items->BeginUpdate(); + lvProcesses->Clear(); + for (n = 0; n < ProcessesNum; n++) + { + if (ProcessIds[n]) + { + _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, ProcessIds[n]); + if (_hProcess) + { + if (lpEnumProcessModules(_hProcess, ModuleHandles, sizeof(ModuleHandles), &ModulesNum)) + { + ModulesNum /= sizeof(ModuleHandles[0]); + _len = lpGetModuleFileNameEx(_hProcess, ModuleHandles[0], _buf, sizeof(_buf)); + _moduleName = String(_buf, _len); + lpGetModuleInformation(_hProcess, ModuleHandles[0], &_moduleInfo, sizeof(_moduleInfo)); + if (_moduleName != "") + { + _pos = _moduleName.LastDelimiter("\\"); + if (_pos) _moduleName = _moduleName.SubString(_pos + 1, _moduleName.Length()); + + _li = lvProcesses->Items->Add(); + _li->Caption = IntToHex((int)ProcessIds[n], 4); + _li->SubItems->Add(_moduleName); + _li->SubItems->Add(IntToHex((int)_moduleInfo.SizeOfImage, 8)); + _li->SubItems->Add(IntToHex((int)_moduleInfo.EntryPoint, 8)); + } + } + CloseHandle(_hProcess); + } + } + } + lvProcesses->Items->EndUpdate(); +} +//--------------------------------------------------------------------------- +void __fastcall TFActiveProcesses::btnCancelClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFActiveProcesses::FormShow(TObject *Sender) +{ + btnDump->Enabled = (lvProcesses->Selected); +} +//--------------------------------------------------------------------------- +void __fastcall TFActiveProcesses::lvProcessesClick(TObject *Sender) +{ + btnDump->Enabled = (lvProcesses->Selected); +} +//--------------------------------------------------------------------------- +void __fastcall TFActiveProcesses::EnumSections(HANDLE HProcess, BYTE* PProcessBase, IMAGE_SECTION_HEADER* Buffer, DWORD* Secnum) +{ + int i; + BYTE *_pBuf, *_pSection; + DWORD _peHdrOffset, _sz; + IMAGE_NT_HEADERS _ntHdr; + IMAGE_SECTION_HEADER _section; + + //Read offset of PE header + if (!ReadProcessMemory(HProcess, PProcessBase + 0x3C, &_peHdrOffset, sizeof(_peHdrOffset), &_sz)) return; + //Read IMAGE_NT_HEADERS.OptionalHeader.BaseOfCode + if (!ReadProcessMemory(HProcess, PProcessBase + _peHdrOffset, &_ntHdr, sizeof(_ntHdr), &_sz)) return; + + _pSection = PProcessBase + _peHdrOffset + 4 + sizeof(_ntHdr.FileHeader) + _ntHdr.FileHeader.SizeOfOptionalHeader; + memset((BYTE*)&_section, 0, sizeof(_section)); + + *Secnum = _ntHdr.FileHeader.NumberOfSections; _pBuf = (BYTE*)Buffer; + for (i = 0; i < _ntHdr.FileHeader.NumberOfSections && i < 64; i++) + { + if (!ReadProcessMemory(HProcess, _pSection + i * sizeof(_section), &_section, sizeof(_section), &_sz)) return; + memmove(_pBuf, &_section, sizeof(_section)); + _pBuf += sizeof(_section); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFActiveProcesses::DumpProcess(DWORD PID, TMemoryStream* MemStream, DWORD* BoC, DWORD* PoC, DWORD* ImB) +{ + WORD _secNum; + DWORD _peHdrOffset, _sz, _sizeOfCode; + DWORD _resPhys, _dd; + BYTE* _buf; + BYTE _b[8]; + HANDLE _hProcess, _hSnapshot; + MODULEINFO _moduleInfo = {0}; + IMAGE_NT_HEADERS _ntHdr; + PROCESSENTRY32 _ppe; + MODULEENTRY32 _pme; + IMAGE_SECTION_HEADER _sections[64]; + + _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, PID); //0x1F0FFF + if (_hProcess) + { + //If Win9x + if (!IsWindows2000OrHigher()) + { + _hSnapshot = lpCreateToolhelp32Snapshot(TH32CS_SNAPALL, GetCurrentProcessId()); + if (_hSnapshot != INVALID_HANDLE_VALUE) + { + _ppe.dwSize = sizeof(PROCESSENTRY32); + _pme.dwSize = sizeof(MODULEENTRY32); + memset(&_ppe.szExeFile, 0, 259); + lpProcess32First(_hSnapshot, &_ppe); + lpModule32First(_hSnapshot, &_pme); + while (lpProcess32Next(_hSnapshot, &_ppe)) + { + lpModule32Next(_hSnapshot, &_pme); + if (_ppe.th32ProcessID == PID) + { + _moduleInfo.lpBaseOfDll = _pme.modBaseAddr; + _moduleInfo.lpBaseOfDll = (BYTE*)0x400000; + } + } + CloseHandle(_hSnapshot); + } + } + else + { + lpEnumProcessModules(_hProcess, ModuleHandles, sizeof(ModuleHandles), &ModulesNum); + lpGetModuleInformation(_hProcess, ModuleHandles[0], &_moduleInfo, sizeof(_moduleInfo)); + } + if (!_moduleInfo.lpBaseOfDll) + { + throw Exception("Invalid process, PID: " + PID); + } + ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + 0x3C, &_peHdrOffset, sizeof(_peHdrOffset), &_sz); + ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + _peHdrOffset, &_ntHdr, sizeof(_ntHdr), &_sz); + EnumSections(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll, _sections, &_sz); + MemStream->Clear(); + //Dump Header + _buf = new BYTE[_ntHdr.OptionalHeader.SizeOfHeaders]; + ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll, _buf, _ntHdr.OptionalHeader.SizeOfHeaders, &_sz); + MemStream->WriteBuffer(_buf, _ntHdr.OptionalHeader.SizeOfHeaders); + delete[] _buf; + if (_sizeOfCode < _sections[1].Misc.VirtualSize) + _sizeOfCode = _sections[1].Misc.VirtualSize; + else + _sizeOfCode = _ntHdr.OptionalHeader.SizeOfCode; + //!!! + MemStream->Clear(); + _buf = new BYTE[_ntHdr.OptionalHeader.SizeOfImage]; + ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll, _buf, _ntHdr.OptionalHeader.SizeOfImage, &_sz); + MemStream->WriteBuffer(_buf, _ntHdr.OptionalHeader.SizeOfImage); + delete[] _buf; + //!!! + /* + //Dump Code + _buf = new BYTE[_sizeOfCode]; + ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + _ntHdr.OptionalHeader.BaseOfCode, _buf, _sizeOfCode, &_sz); + MemStream->WriteBuffer(_buf, _sizeOfCode); + delete[] _buf; + //Find EP + //Dump Resources + MemStream->Seek(0, soFromEnd); + _buf = new BYTE[_ntHdr.OptionalHeader.DataDirectory[2].Size]; + ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + _ntHdr.OptionalHeader.DataDirectory[2].VirtualAddress, _buf, _ntHdr.OptionalHeader.DataDirectory[2].Size, &_sz); + _resPhys = MemStream->Size; + MemStream->WriteBuffer(_buf, _ntHdr.OptionalHeader.DataDirectory[2].Size); + delete[] _buf; + */ + //Correct PE Header + //Set SectionNum = 2 + MemStream->Seek(6 + _peHdrOffset, soFromBeginning); + _secNum = 2; + MemStream->WriteBuffer(&_secNum, sizeof(_secNum)); + //Set EP + //Set sections + MemStream->Seek(0xF8 + _peHdrOffset, soFromBeginning); + //"CODE" + memset(_b, 0, 8); _b[0] = 'C'; _b[1] = 'O'; _b[2] = 'D'; _b[3] = 'E'; + MemStream->WriteBuffer(_b, 8); + _dd = _sizeOfCode; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + _dd = _ntHdr.OptionalHeader.BaseOfCode; + MemStream->WriteBuffer(&_dd, 4);//RVA + _dd = _sizeOfCode; + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + _dd = _ntHdr.OptionalHeader.SizeOfHeaders; + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0x60000020; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + /* + //"DATA" + memset(_b, 0, 8); _b[0] = 'D'; _b[1] = 'A'; _b[2] = 'T'; _b[3] = 'A'; + MemStream->WriteBuffer(_b, 8); + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//RVA + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0xC0000040; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + //"BSS" + memset(_b, 0, 8); _b[0] = 'B'; _b[1] = 'S'; _b[2] = 'S'; + MemStream->WriteBuffer(_b, 8); + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//RVA + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0xC0000040; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + //".idata" + memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'i'; _b[2] = 'd'; _b[3] = 'a'; _b[4] = 't'; _b[5] = 'a'; + MemStream->WriteBuffer(_b, 8); + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//RVA + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0xC0000040; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + //".tls" + memset(_b, 0, 8); _b[0] = '.'; _b[1] = 't'; _b[2] = 'l'; _b[3] = 's'; + MemStream->WriteBuffer(_b, 8); + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//RVA + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0xC0000000; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + //".rdata" + memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'r'; _b[2] = 'd'; _b[3] = 'a'; _b[4] = 't'; _b[5] = 'a'; + MemStream->WriteBuffer(_b, 8); + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//RVA + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0x50000040; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + //".reloc" + memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'r'; _b[2] = 'e'; _b[3] = 'l'; _b[4] = 'o'; _b[5] = 'c'; + MemStream->WriteBuffer(_b, 8); + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//RVA + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0x50000040; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + */ + //".rsrc" + memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'r'; _b[2] = 's'; _b[3] = 'r'; _b[4] = 'c'; + MemStream->WriteBuffer(_b, 8); + _dd = _ntHdr.OptionalHeader.DataDirectory[2].Size; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + _dd = _ntHdr.OptionalHeader.DataDirectory[2].VirtualAddress; + MemStream->WriteBuffer(&_dd, 4);//RVA + _dd = _ntHdr.OptionalHeader.DataDirectory[2].Size; + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE + _dd = _resPhys; + MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR + MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR + MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM + _dd = 0x50000040; + MemStream->WriteBuffer(&_dd, 4);//FLAGS + /* + //Correct directories + MemStream->Seek(0x78 + _peHdrOffset, soFromBeginning); + //Export table + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VA + MemStream->WriteBuffer(&_dd, 4);//Size + //Import table + _dd = 0; + MemStream->WriteBuffer(&_dd, 4);//VA + MemStream->WriteBuffer(&_dd, 4);//Size + //Resource table + _dd = _ntHdr.OptionalHeader.SizeOfHeaders; + MemStream->WriteBuffer(&_dd, 4);//RVA + _dd = _ntHdr.OptionalHeader.DataDirectory[2].Size; + MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE + */ + FMain_11011981->EvaluateInitTable((BYTE*)MemStream->Memory, MemStream->Size, _ntHdr.OptionalHeader.ImageBase + _ntHdr.OptionalHeader.SizeOfHeaders); + + CloseHandle(_hProcess); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFActiveProcesses::btnDumpClick(TObject *Sender) +{ + DWORD _pid, _boc, _poc, _imb; + TListItem *_li; + TMemoryStream *_stream; + TMemoryStream *_stream1; + String _item; + + if (lvProcesses->Selected) + { + try + { + _li = lvProcesses->Selected; + _pid = StrToInt("0x" + _li->Caption); + _stream = new TMemoryStream; + DumpProcess(_pid, _stream, &_boc, &_poc, &_imb); + if (!_stream->Size) + { + delete _stream; + return; + } + _stream->SaveToFile("__idrtmp__.exe"); + delete _stream; + FMain_11011981->DoOpenDelphiFile(DELHPI_VERSION_AUTO, "__idrtmp__.exe", false, false); + } + catch(const Exception &ex) + { + ShowMessage("Dumper failed: " + ex.Message); + } + } + Close(); +} +//--------------------------------------------------------------------------- diff --git a/Sources/Forms/ActiveProcesses.dfm b/ActiveProcesses.dfm similarity index 51% rename from Sources/Forms/ActiveProcesses.dfm rename to ActiveProcesses.dfm index 59aeb04..4d322b2 100644 --- a/Sources/Forms/ActiveProcesses.dfm +++ b/ActiveProcesses.dfm @@ -2,9 +2,9 @@ object FActiveProcesses: TFActiveProcesses Left = 390 Top = 440 BorderStyle = bsSingle - Caption = 'Active Processes (x86)' + Caption = 'Active Processes' ClientHeight = 310 - ClientWidth = 640 + ClientWidth = 792 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -16,59 +16,60 @@ object FActiveProcesses: TFActiveProcesses OnShow = FormShow PixelsPerInch = 96 TextHeight = 13 - object ListViewProcesses: TListView + object btnDump: TButton + Left = 171 + Top = 286 + Width = 61 + Height = 20 + Caption = 'Dump' + TabOrder = 1 + OnClick = btnDumpClick + end + object btnCancel: TButton + Left = 561 + Top = 286 + Width = 61 + Height = 20 + Caption = 'Cancel' + TabOrder = 2 + OnClick = btnCancelClick + end + object lvProcesses: TListView Left = 0 Top = 0 - Width = 640 - Height = 310 - Align = alClient - BorderStyle = bsNone + Width = 792 + Height = 280 + Align = alTop Columns = < item Caption = 'PID' + Width = 65 end item Caption = 'Name' - Width = 200 + Width = 325 end item Caption = 'Image Size' - Width = 120 + Width = 122 end item - Caption = 'Entry Point' - Width = 120 + Caption = 'EP' + Width = 122 end item - Caption = 'Base Address' - Width = 120 + Caption = 'Base' + Width = 122 end> Font.Charset = RUSSIAN_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] - ReadOnly = True RowSelect = True ParentFont = False - PopupMenu = PMProcess TabOrder = 0 ViewStyle = vsReport - end - object PMProcess: TPopupMenu - OnPopup = PMProcessPopup - Left = 40 - Top = 40 - object PMProcessDump: TMenuItem - Caption = 'Dump' - OnClick = PMProcessDumpClick - end - object N1: TMenuItem - Caption = '-' - end - object PMProcessRefresh: TMenuItem - Caption = 'Refresh' - OnClick = PMProcessRefreshClick - end + OnClick = lvProcessesClick end end diff --git a/ActiveProcesses.h b/ActiveProcesses.h new file mode 100644 index 0000000..ecb9759 --- /dev/null +++ b/ActiveProcesses.h @@ -0,0 +1,70 @@ +//--------------------------------------------------------------------------- + +#ifndef ActiveProcessesH +#define ActiveProcessesH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFActiveProcesses : public TForm +{ +__published: // IDE-managed Components + TButton *btnDump; + TButton *btnCancel; + TListView *lvProcesses; + void __fastcall btnCancelClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall btnDumpClick(TObject *Sender); + void __fastcall lvProcessesClick(TObject *Sender); +private: // User declarations + HINSTANCE InstKernel32; + HINSTANCE InstPSAPI; + DWORD ProcessesNum; + DWORD ModulesNum; + DWORD ProcessIds[1024]; + HMODULE ModuleHandles[1024]; + +typedef HANDLE __stdcall (*TCreateToolhelp32Snapshot)(DWORD dwFlags, DWORD th32ProcessID); +typedef BOOL __stdcall (*TProcess32First)(HANDLE hSnapshot, PROCESSENTRY32* lppe); +typedef BOOL __stdcall (*TProcess32Next)(HANDLE hSnapshot, PROCESSENTRY32* lppe); +typedef BOOL __stdcall (*TModule32First)(HANDLE hSnapshot, MODULEENTRY32* lpme); +typedef BOOL __stdcall (*TModule32Next)(HANDLE hSnapshot, MODULEENTRY32* lpme); + + TCreateToolhelp32Snapshot lpCreateToolhelp32Snapshot; + TProcess32First lpProcess32First; + TProcess32Next lpProcess32Next; + TModule32First lpModule32First; + TModule32Next lpModule32Next; + +typedef BOOL __stdcall (*TEnumProcesses)(HANDLE lpidProcess, DWORD cb, PDWORD cbNeeded); +typedef BOOL __stdcall (*TEnumProcessModules)(HANDLE hProcess, HMODULE lphModule, DWORD cb, PDWORD lpcbNeeded); +typedef DWORD __stdcall (*TGetModuleFileNameEx)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize); +typedef BOOL __stdcall (*TGetModuleInformation)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb); + + TEnumProcesses lpEnumProcesses; + TEnumProcessModules lpEnumProcessModules; + TGetModuleFileNameEx lpGetModuleFileNameEx; + TGetModuleInformation lpGetModuleInformation; + + bool IsWindows2000OrHigher(); + void ShowProcesses95(); + void ShowProcessesNT(); + +public: // User declarations + __fastcall TFActiveProcesses(TComponent* Owner); + __fastcall ~TFActiveProcesses(); + + void ShowProcesses(); + void __fastcall EnumSections(HANDLE HProcess, BYTE* PProcessBase, IMAGE_SECTION_HEADER* Buffer, DWORD* Secnum); + void __fastcall DumpProcess(DWORD PID, TMemoryStream* MemStream, DWORD* BoC, DWORD* PoC, DWORD* ImB); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFActiveProcesses *FActiveProcesses; +//--------------------------------------------------------------------------- +#endif diff --git a/Analyze1.cpp b/Analyze1.cpp new file mode 100644 index 0000000..f5ac216 --- /dev/null +++ b/Analyze1.cpp @@ -0,0 +1,790 @@ +//--------------------------------------------------------------------------- +//Create XRefs +//Scan procedure calls (include constructors and destructors) +//Calculate size of stack for arguments +void __fastcall TFMain_11011981::AnalyzeProc1(DWORD fromAdr, char xrefType, DWORD xrefAdr, int xrefOfs, bool maybeEmb) +{ + BYTE op, b1, b2; + bool bpBased = false; + WORD bpBase = 4; + int num, skipNum, instrLen, instrLen1, instrLen2, procSize; + DWORD b; + int fromPos, curPos, Pos, Pos1, Pos2; + DWORD curAdr, Adr, Adr1, finallyAdr, endAdr, maxAdr; + DWORD lastMovTarget = 0, lastCmpPos = 0, lastAdr = 0; + PInfoRec recN, recN1; + PXrefRec recX; + DISINFO DisInfo; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return; + + if (IsFlagSet(cfEmbedded, fromPos)) return; + + recN = GetInfoRec(fromAdr); + + //Virtual constructor - don't analyze + if (recN && recN->type.Pos("class of ") == 1) return; + + if (!recN) + { + recN = new InfoRec(fromPos, ikRefine); + } + else if (recN->kind == ikUnknown || recN->kind == ikData) + { + recN->kind = ikRefine; + recN->procInfo = new InfoProcInfo; + } + + //If xrefAdr != 0, add it to recN->xrefs + if (xrefAdr) + { + recN->AddXref(xrefType, xrefAdr, xrefOfs); + SetFlag(cfProcStart, Adr2Pos(xrefAdr)); + } + + //Don't analyze imports + if (IsFlagSet(cfImport, fromPos)) return; + //if (IsFlagSet(cfExport, fromPos)) return; + + //If Pass1 was set skip analyze + if (IsFlagSet(cfPass1, fromPos)) return; + + if (!IsFlagSet(cfPass0, fromPos)) + AnalyzeProcInitial(fromAdr); + SetFlag(cfProcStart | cfPass1, fromPos); + + if (maybeEmb && !(recN->procInfo->flags & PF_EMBED)) recN->procInfo->flags |= PF_MAYBEEMBED; + procSize = GetProcSize(fromAdr); + curPos = fromPos; curAdr = fromAdr; + + while (1) + { + if (curAdr >= CodeBase + TotalSize) break; +//---------------------------------- Try +// xor reg, reg cfTry | cfSkip +// push ebp cfSkip +// push offset @1 cfSkip +// push fs:[reg] cfSkip +// mov fs:[reg], esp cfSkip +// +//---------------------------------- OnFinally +// xor reg, reg cfFinally | cfSkip +// pop reg cfSkip +// pop reg cfSkip +// pop reg cfSkip +// mov fs:[reg], esp cfSkip +//Adr1-1: push offset @3 cfSkip +//@2: ... +// ret cfSkip +//---------------------------------- Finally +//@1: jmp @HandleFinally cfFinally | cfSkip +// jmp @2 cfFinally | cfSkip +//@3: ... end of Finally Section +//---------------------------------- Except +// xor reg, reg cfExcept | cfSkip +// pop reg cfSkip +// pop reg cfSkip +// pop reg cfSkip +// mov fs:[reg], esp cfSkip +// jmp @3 -> End of Exception Section cfSkip +//@1: jmp @HandleAnyException cfExcept | cfSkip +// ... +// call DoneExcept +// ... +//@3: ... +//---------------------------------- Except (another variant, rear) +// pop fs:[0] cfExcept | cfSkip +// add esp,8 cfSkip +// jmp @3 -> End of Exception Section cfSkip +//@1: jmp @HandleAnyException cfExcept | cfSkip +// ... +// call DoneExcept +// ... +//@3: ... +//---------------------------------- OnExcept +// xor reg, reg cfExcept | cfSkip +// pop reg cfSkip +// pop reg cfSkip +// pop reg cfSkip +// mov fs:[reg], esp cfSkip +// jmp @3 -> End of Exception Section cfSkip +//@1: jmp HandleOnException cfExcept | cfSkip +// dd num cfETable +//Table from num records: +// dd offset ExceptionInfo +// dd offset ExceptionProc +// ... +//@3: ... +//---------------------------------- + //Is it try section begin (skipNum > 0)? + skipNum = IsTryBegin(curAdr, &finallyAdr) + IsTryBegin0(curAdr, &finallyAdr); + if (skipNum > 0) + { + Adr = finallyAdr; //Adr=@1 + Pos = Adr2Pos(Adr); if (Pos < 0) break; + if (Adr > lastAdr) lastAdr = Adr; + SetFlag(cfTry, curPos); + SetFlags(cfSkip, curPos, skipNum); + + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN1 = GetInfoRec(DisInfo.Immediate); + if (recN1 && recN1->HasName()) + { + //jmp @HandleFinally + if (recN1->SameName("@HandleFinally")) + { + SetFlag(cfFinally, Pos);//@1 + SetFlags(cfSkip, Pos - 1, instrLen1 + 1); //ret + jmp HandleFinally + + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Pos2Adr(Pos), &DisInfo, 0); + SetFlag(cfFinally, Pos);//jmp @2 + SetFlags(cfSkip, Pos, instrLen2);//jmp @2 + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + + Pos = Adr2Pos(DisInfo.Immediate);//@2 + //Get prev (before Pos) instruction + Pos1 = GetNearestUpInstruction(Pos); + instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); + //If push XXXXXXXX -> set new lastAdr + if (Disasm.GetOp(DisInfo.Mnem) == OP_PUSH) + { + SetFlags(cfSkip, Pos1, instrLen2); + if (DisInfo.OpType[0] == otIMM && DisInfo.Immediate > lastAdr) lastAdr = DisInfo.Immediate; + } + + //Find nearest up instruction with segment prefix fs: + Pos1 = GetNearestUpPrefixFs(Pos); + instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); + //pop fs:[0] + if (Disasm.GetOp(DisInfo.Mnem) == OP_POP) + { + SetFlags(cfSkip, Pos1, Pos - Pos1); + } + //mov fs:[0],reg + else if (DisInfo.OpType[0] == otMEM && DisInfo.BaseReg == -1 && DisInfo.Offset == 0) + { + Pos2 = GetNthUpInstruction(Pos1, 3); + SetFlag(cfFinally, Pos2); + SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); + } + //mov fs:[reg1], reg2 + else + { + Pos2 = GetNthUpInstruction(Pos1, 4); + SetFlag(cfFinally, Pos2); + SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); + } + } + else if (recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleAutoException")) + { + SetFlag(cfExcept, Pos);//@1 + //Find nearest up instruction with segment prefix fs: + Pos1 = GetNearestUpPrefixFs(Pos); + instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); + //pop fs:[0] + if (Disasm.GetOp(DisInfo.Mnem) == OP_POP) + { + SetFlags(cfSkip, Pos1, Pos - Pos1); + } + //mov fs:[0],reg + else if (DisInfo.OpType[0] == otMEM && DisInfo.BaseReg == -1 && DisInfo.Offset == 0) + { + Pos2 = GetNthUpInstruction(Pos1, 3); + SetFlag(cfExcept, Pos2); + SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); + } + //mov fs:[reg1], reg2 + else + { + Pos2 = GetNthUpInstruction(Pos1, 4); + SetFlag(cfExcept, Pos2); + SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); + } + + //Get prev (before Pos) instruction + Pos1 = GetNearestUpInstruction(Pos); + Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); + //If jmp -> set new lastAdr + if (Disasm.GetOp(DisInfo.Mnem) == OP_JMP && DisInfo.Immediate > lastAdr) lastAdr = DisInfo.Immediate; + } + else if (recN1->SameName("@HandleOnException")) + { + SetFlag(cfExcept, Pos);//@1 + //Find nearest up instruction with segment prefix fs: + Pos1 = GetNearestUpPrefixFs(Pos); + instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); + //pop fs:[0] + if (Disasm.GetOp(DisInfo.Mnem) == OP_POP) + { + SetFlags(cfSkip, Pos1, Pos - Pos1); + } + //mov fs:[0],reg + else if (DisInfo.OpType[0] == otMEM && DisInfo.BaseReg == -1 && DisInfo.Offset == 0) + { + Pos2 = GetNthUpInstruction(Pos1, 3); + SetFlag(cfExcept, Pos2); + SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); + } + //mov fs:[reg1], reg2 + else + { + Pos2 = GetNthUpInstruction(Pos1, 4); + SetFlag(cfExcept, Pos2); + SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); + } + + //Get prev (before Pos) instruction + Pos1 = GetNearestUpInstruction(Pos); + Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); + //If jmp -> set new lastAdr + if (Disasm.GetOp(DisInfo.Mnem) == OP_JMP && DisInfo.Immediate > lastAdr) lastAdr = DisInfo.Immediate; + + //Next instruction + Pos += instrLen1; Adr += instrLen1; + //Set flag cfETable + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); + SetFlags(cfSkip, Pos, 4); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + SetFlags(cfSkip, Pos, 4); Pos += 4; + //dd offset ExceptionProc + DWORD procAdr = *((DWORD*)(Code + Pos)); + if (IsValidCodeAdr(procAdr)) SetFlag(cfLoc, Adr2Pos(procAdr)); + SetFlags(cfSkip, Pos, 4); Pos += 4; + } + } + } + curPos += skipNum; curAdr += skipNum; + continue; + } + //Is it finally section? + skipNum = IsTryEndPush(curAdr, &endAdr); + if (skipNum > 0) + { + SetFlag(cfFinally, curPos); + SetFlags(cfSkip, curPos, skipNum); + if (endAdr > lastAdr) lastAdr = endAdr; + curPos += skipNum; curAdr += skipNum; + continue; + } + //Finally section in if...then...else constructions + skipNum = IsTryEndJump(curAdr, &endAdr); + if (skipNum > 0) + { + SetFlag(cfFinally | cfExcept, curPos); + SetFlags(cfSkip, curPos, skipNum); + if (endAdr > lastAdr) lastAdr = endAdr; + curPos += skipNum; curAdr += skipNum; + continue; + } + //Int64NotEquality + //skipNum = ProcessInt64NotEquality(curAdr, &maxAdr); + //if (skipNum > 0) + //{ + // if (maxAdr > lastAdr) lastAdr = maxAdr; + // curPos += skipNum; curAdr += skipNum; + // continue; + //} + //Int64Equality + //skipNum = ProcessInt64Equality(curAdr, &maxAdr); + //if (skipNum > 0) + //{ + // if (maxAdr > lastAdr) lastAdr = maxAdr; + // curPos += skipNum; curAdr += skipNum; + // continue; + //} + //Int64Comparison + skipNum = ProcessInt64Comparison(curAdr, &maxAdr); + if (skipNum > 0) + { + if (maxAdr > lastAdr) lastAdr = maxAdr; + curPos += skipNum; curAdr += skipNum; + continue; + } + //Int64ComparisonViaStack1 + skipNum = ProcessInt64ComparisonViaStack1(curAdr, &maxAdr); + if (skipNum > 0) + { + if (maxAdr > lastAdr) lastAdr = maxAdr; + curPos += skipNum; curAdr += skipNum; + continue; + } + //Int64ComparisonViaStack2 + skipNum = ProcessInt64ComparisonViaStack2(curAdr, &maxAdr); + if (skipNum > 0) + { + if (maxAdr > lastAdr) lastAdr = maxAdr; + curPos += skipNum; curAdr += skipNum; + continue; + } + //Skip exception table + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + curPos += 4 + 8*num; curAdr += 4 + 8*num; + continue; + } + b1 = Code[curPos]; + b2 = Code[curPos + 1]; + if (!b1 && !b2 && !lastAdr) break; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) break; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + op = Disasm.GetOp(DisInfo.Mnem); + //Code + SetFlags(cfCode, curPos, instrLen); + //Instruction begin + SetFlag(cfInstruction, curPos); + + if (curAdr >= lastAdr) lastAdr = 0; + + //Frame instructions + if (curAdr == fromAdr && b1 == 0x55) //push ebp + { + SetFlag(cfFrame, curPos); + } + if (b1 == 0x8B && b2 == 0xEC) //mov ebp, esp + { + bpBased = true; + recN->procInfo->flags |= PF_BPBASED; + recN->procInfo->bpBase = bpBase; + + SetFlags(cfFrame, curPos, instrLen); + curPos += instrLen; curAdr += instrLen; + continue; + } + if (b1 == 0x8B && b2 == 0xE5) //mov esp, ebp + { + SetFlags(cfFrame, curPos, instrLen); + curPos += instrLen; curAdr += instrLen; + continue; + } + if (op == OP_JMP) + { + if (curAdr == fromAdr) break; + if (DisInfo.OpType[0] == otMEM) + { + if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) break; + } + if (DisInfo.OpType[0] == otIMM) + { + Adr = DisInfo.Immediate; Pos = Adr2Pos(Adr); + if (Pos < 0 && (!lastAdr || curAdr == lastAdr)) break; + if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) break; + SetFlag(cfLoc, Pos); + recN1 = GetInfoRec(Adr); + if (!recN1) recN1 = new InfoRec(Pos, ikUnknown); + recN1->AddXref('J', fromAdr, curAdr - fromAdr); + + if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) break; + } + } + + //End of procedure + if (DisInfo.Ret) + { + if (!lastAdr || curAdr == lastAdr) + { + //Proc end + //SetFlag(cfProcEnd, curPos + instrLen - 1); + recN->procInfo->procSize = curAdr - fromAdr + instrLen; + recN->procInfo->retBytes = 0; + //ret N + if (DisInfo.OpNum) + { + recN->procInfo->retBytes = DisInfo.Immediate;//num; + } + break; + } + } + //push + if (op == OP_PUSH) + { + SetFlag(cfPush, curPos); + bpBase += 4; + } + //pop + if (op == OP_POP) SetFlag(cfPop, curPos); + //add (sub) esp,... + if (DisInfo.OpRegIdx[0] == 20 && DisInfo.OpType[1] == otIMM) + { + if (op == OP_ADD) bpBase -= (int)DisInfo.Immediate; + if (op == OP_SUB) bpBase += (int)DisInfo.Immediate; + //skip + SetFlags(cfSkip, curPos, instrLen); + curPos += instrLen; curAdr += instrLen; + continue; + } + ////fstp [esp] + //if (!memcmp(DisInfo.Mnem, "fst", 3) && DisInfo.BaseReg == 20) SetFlag(cfFush, curPos); + + //skip + if (!memcmp(DisInfo.Mnem, "sahf", 4) || !memcmp(DisInfo.Mnem, "wait", 4)) + { + SetFlags(cfSkip, curPos, instrLen); + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (op == OP_MOV) lastMovTarget = DisInfo.Offset; + if (op == OP_CMP) lastCmpPos = curPos; + + //Is instruction (not call and jmp), that contaibs operand [reg+xxx], where xxx is negative value + if (maybeEmb && !DisInfo.Call && !DisInfo.Branch && (int)DisInfo.Offset < 0 && + (DisInfo.IndxReg == -1 && (DisInfo.BaseReg >= 16 && DisInfo.BaseReg <= 23 && DisInfo.BaseReg != 20 && DisInfo.BaseReg != 21))) + { + //May be add condition that all Xrefs must points to one subroutine!!!!!!!!!!!!! + if ((bpBased && DisInfo.BaseReg != 21) || (!bpBased && DisInfo.BaseReg != 20)) + { + recN->procInfo->flags |= PF_EMBED; + } + } + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + if (!IsValidCodeAdr(DisInfo.Offset)) + { + //SetFlag(cfProcEnd, curPos + instrLen - 1); + recN->procInfo->procSize = curAdr - fromAdr + instrLen; + break; + } + DWORD cTblAdr = 0, jTblAdr = 0; + SetFlag(cfSwitch, lastCmpPos); + SetFlag(cfSwitch, curPos); + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Table address - last 4 bytes of instruction + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Scan gap to find table cTbl + if (Adr <= lastMovTarget && lastMovTarget < jTblAdr) cTblAdr = lastMovTarget; + //If exists cTblAdr, skip it + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + SetFlags(cfSkip, Pos, CNum); + Pos += CNum; Adr += CNum; + } + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + SetFlags(cfSkip, Pos, 4); + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //Check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0 && Pos - NPos < MAX_DISASSEMBLE) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + if (Code[NPos + 2] == 0x35) + { + SetFlag(cfTry, NPos - 6); + SetFlags(cfSkip, NPos - 6, 20); + } + else + { + SetFlag(cfTry, NPos - 8); + SetFlags(cfSkip, NPos - 8, 14); + } + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN1 = GetInfoRec(DisInfo.Immediate); + if (recN1 && recN1->HasName()) + { + //jmp @HandleFinally + if (recN1->SameName("@HandleFinally")) + { + SetFlag(cfFinally, Pos); + + SetFlags(cfSkip, Pos - 1, instrLen1 + 1); //ret + jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + SetFlag(cfFinally, Pos); + SetFlags(cfSkip, Pos, instrLen2); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + //int hfEndPos = Adr2Pos(Adr); + + int hfStartPos = Adr2Pos(DisInfo.Immediate); assert(hfStartPos >= 0); + + Pos = hfStartPos - 5; + + if (Code[Pos] == 0x68) //push offset @3 //Flags[Pos] & cfInstruction must be != 0 + { + hfStartPos = Pos - 8; + SetFlags(cfSkip, hfStartPos, 13); + } + SetFlag(cfFinally, hfStartPos); + } + else if (recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleAutoException")) + { + SetFlag(cfExcept, Pos); + + int hoStartPos = Pos - 10; + SetFlags(cfSkip, hoStartPos, instrLen1 + 10); + Disasm.Disassemble(Code + Pos - 10, (__int64)(Adr - 10), &DisInfo, 0); + if (Disasm.GetOp(DisInfo.Mnem) != OP_XOR || DisInfo.OpRegIdx[0] != DisInfo.OpRegIdx[1]) + { + hoStartPos = Pos - 13; + SetFlags(cfSkip, hoStartPos, instrLen1 + 13); + } + //Find prev jmp + Pos1 = hoStartPos; Adr1 = Pos2Adr(Pos1); + for (int k = 0; k < 6; k++) + { + instrLen2 = Disasm.Disassemble(Code + Pos1, (__int64)Adr1, &DisInfo, 0); + Pos1 += instrLen2; + Adr1 += instrLen2; + } + if (DisInfo.Immediate > lastAdr) lastAdr = DisInfo.Immediate; + //int hoEndPos = Adr2Pos(DisInfo.Immediate); + + SetFlag(cfExcept, hoStartPos); + } + else if (recN1->SameName("@HandleOnException")) + { + SetFlag(cfExcept, Pos); + + int hoStartPos = Pos - 10; + SetFlags(cfSkip, hoStartPos, instrLen1 + 10); + Disasm.Disassemble(Code + Pos - 10, (__int64)(Adr - 10), &DisInfo, 0); + if (Disasm.GetOp(DisInfo.Mnem) != OP_XOR || DisInfo.OpRegIdx[0] != DisInfo.OpRegIdx[1]) + { + hoStartPos = Pos - 13; + SetFlags(cfSkip, hoStartPos, instrLen1 + 13); + } + //Find prev jmp + Pos1 = hoStartPos; Adr1 = Pos2Adr(Pos1); + for (int k = 0; k < 6; k++) + { + instrLen2 = Disasm.Disassemble(Code + Pos1, (__int64)Adr1, &DisInfo, 0); + Pos1 += instrLen2; + Adr1 += instrLen2; + } + if (DisInfo.Immediate > lastAdr) lastAdr = DisInfo.Immediate; + //int hoEndPos = Adr2Pos(DisInfo.Immediate); + + SetFlag(cfExcept, hoStartPos); + + //Next instruction + Pos += instrLen1; Adr += instrLen1; + //Set flag cfETable + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); + SetFlags(cfSkip, Pos, 4); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + SetFlags(cfSkip, Pos, 4); Pos += 4; + //dd offset ExceptionProc + DWORD procAdr = *((DWORD*)(Code + Pos)); + if (IsValidCodeAdr(procAdr)) SetFlag(cfLoc, Adr2Pos(procAdr)); + SetFlags(cfSkip, Pos, 4); Pos += 4; + } + } + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + if (DisInfo.Call) + { + SetFlag(cfCall, curPos); + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr) && Adr2Pos(Adr) >= 0) + { + SetFlag(cfLoc, Adr2Pos(Adr)); + //If after call exists instruction pop ecx, it may be embedded procedure + bool mbemb = (Code[curPos + instrLen] == 0x59); + AnalyzeProc1(Adr, 'C', fromAdr, curAdr - fromAdr, mbemb); + + recN1 = GetInfoRec(Adr); + if (recN1 && recN1->procInfo) + { + //After embedded proc instruction pop ecx must be skipped + if (mbemb && recN1->procInfo->flags & PF_EMBED) + SetFlag(cfSkip, curPos + instrLen); + + if (recN1->HasName()) + { + if (recN1->SameName("@Halt0")) + { + SetFlags(cfSkip, curPos, instrLen); + if (fromAdr == EP && !lastAdr) + { + //SetFlag(cfProcEnd, curPos + instrLen - 1); + recN->procInfo->procSize = curAdr - fromAdr + instrLen; + recN->SetName("EntryPoint"); + recN->procInfo->retBytes = 0; + break; + } + } + + int begPos, endPos; + //If called procedure is @ClassCreate, then current procedure is constructor + if (recN1->SameName("@ClassCreate")) + { + recN->kind = ikConstructor; + //Code from instruction test... until this call is not sufficient (mark skipped) + begPos = GetNearestUpInstruction1(curPos, fromPos, "test"); + if (begPos != -1) SetFlags(cfSkip, begPos, curPos + instrLen - begPos); + } + else if (recN1->SameName("@AfterConstruction")) + { + begPos = GetNearestUpInstruction2(curPos, fromPos, "test", "cmp"); + endPos = GetNearestDownInstruction(curPos, "add"); + if (begPos != -1 && endPos != -1) SetFlags(cfSkip, begPos, endPos - begPos); + } + else if (recN1->SameName("@BeforeDestruction")) + SetFlag(cfSkip, curPos); + //If called procedure is @ClassDestroy, then current procedure is destructor + else if (recN1->SameName("@ClassDestroy")) + { + recN->kind = ikDestructor; + begPos = GetNearestUpInstruction2(curPos, fromPos, "test", "cmp"); + if (begPos != -1) SetFlags(cfSkip, begPos, curPos + instrLen - begPos); + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (b1 == 0xEB || //short relative abs jmp or cond jmp + (b1 >= 0x70 && b1 <= 0x7F) || + (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + Pos = Adr2Pos(Adr); + if (!IsFlagSet(cfEmbedded, Pos))//Possible branch to start of Embedded proc (for ex. in proc TextToFloat)) + { + SetFlag(cfLoc, Pos); + //Mark possible start of Loop + if (Adr < curAdr && !IsFlagSet(cfFinally, Adr2Pos(curAdr)) && !IsFlagSet(cfExcept, Adr2Pos(curAdr))) + SetFlag(cfLoop, Pos); + recN1 = GetInfoRec(Adr); + if (!recN1) recN1 = new InfoRec(Pos, ikUnknown); + recN1->AddXref('C', fromAdr, curAdr - fromAdr); + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + if (b1 == 0xE9) //relative abs jmp or cond jmp + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + Pos = Adr2Pos(Adr); + SetFlag(cfLoc, Pos); + //Mark possible start of Loop + if (Adr < curAdr && !IsFlagSet(cfFinally, Adr2Pos(curAdr)) && !IsFlagSet(cfExcept, Adr2Pos(curAdr))) + SetFlag(cfLoop, Pos); + recN1 = GetInfoRec(Adr); + if (recN1 && recN1->HasName()) + { + if (recN1->SameName("@HandleFinally") || + recN1->SameName("@HandleAnyException") || + recN1->SameName("@HandleOnException") || + recN1->SameName("@HandleAutoException")) + { + recN1->AddXref('J', fromAdr, curAdr - fromAdr); + } + } + if (!recN1 && Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + //Second operand - immediate and is valid address + if (DisInfo.OpType[1] == otIMM) + { + Pos = Adr2Pos(DisInfo.Immediate); + //imm32 must be valid code address outside current procedure + if (Pos >= 0 && IsValidCodeAdr(DisInfo.Immediate) && (DisInfo.Immediate < fromAdr || DisInfo.Immediate >= fromAdr + procSize)) + { + //Position must be free + if (!Flags[Pos]) + { + //No Name + if (!Infos[Pos]) + { + //Address must be outside current procedure + if (DisInfo.Immediate < fromAdr || DisInfo.Immediate >= fromAdr + procSize) + { + //If valid code lets user decide later + int codeValidity = IsValidCode(DisInfo.Immediate); + + if (codeValidity == 1) //Code + AnalyzeProc1(DisInfo.Immediate, 'D', fromAdr, curAdr - fromAdr, false); + } + } + } + //If slot is not free (procedure is already loaded) + else if (IsFlagSet(cfProcStart, Pos)) + AnalyzeProc1(DisInfo.Immediate, 'D', fromAdr, curAdr - fromAdr, false); + } + curPos += instrLen; curAdr += instrLen; + continue; + } + curPos += instrLen; curAdr += instrLen; + } +} +//--------------------------------------------------------------------------- + diff --git a/Analyze2.cpp b/Analyze2.cpp new file mode 100644 index 0000000..ca16d20 --- /dev/null +++ b/Analyze2.cpp @@ -0,0 +1,2982 @@ +void __fastcall AddFieldXref(PFIELDINFO fInfo, DWORD ProcAdr, int ProcOfs, char type); +//--------------------------------------------------------------------------- +//structure for saving context of all registers (branch instruction) +typedef struct +{ + int sp; + DWORD adr; + RINFO registers[32]; +} RCONTEXT, *PRCONTEXT; +//--------------------------------------------------------------------------- +PRCONTEXT __fastcall GetCtx(TList* Ctx, DWORD Adr) +{ + for (int n = 0; n < Ctx->Count; n++) + { + PRCONTEXT rinfo = (PRCONTEXT)Ctx->Items[n]; + if (rinfo->adr == Adr) return rinfo; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall SetRegisterValue(PRINFO regs, int Idx, DWORD Value) +{ + if (Idx >= 16 && Idx <= 19) + { + regs[Idx - 16].value = Value; + regs[Idx - 12].value = Value; + regs[Idx - 8].value = Value; + regs[Idx].value = Value; + return; + } + if (Idx >= 20 && Idx <= 23) + { + regs[Idx - 8].value = Value; + regs[Idx].value = Value; + return; + } + if (Idx >= 0 && Idx <= 3) + { + regs[Idx].value = Value; + regs[Idx + 8].value = Value; + regs[Idx + 16].value = Value; + return; + } + if (Idx >= 4 && Idx <= 7) + { + regs[Idx].value = Value; + regs[Idx + 4].value = Value; + regs[Idx + 12].value = Value; + return; + } + if (Idx >= 8 && Idx <= 11) + { + regs[Idx - 8].value = Value; + regs[Idx - 4].value = Value; + regs[Idx].value = Value; + regs[Idx + 8].value = Value; + return; + } + if (Idx >= 12 && Idx <= 15) + { + regs[Idx].value = Value; + regs[Idx + 8].value = Value; + return; + } +} +//--------------------------------------------------------------------------- +//Possible values +//'V' - Virtual table base (for calls processing) +//'v' - var +//'L' - lea local var +//'l' - local var +//'A' - lea argument +//'a' - argument +//'I' - Integer +void __fastcall SetRegisterSource(PRINFO regs, int Idx, char Value) +{ + if (Idx >= 16 && Idx <= 19) + { + regs[Idx - 16].source = Value; + regs[Idx - 12].source = Value; + regs[Idx - 8].source = Value; + regs[Idx].source = Value; + return; + } + if (Idx >= 20 && Idx <= 23) + { + regs[Idx - 8].source = Value; + regs[Idx].source = Value; + return; + } + if (Idx >= 0 && Idx <= 3) + { + regs[Idx].source = Value; + regs[Idx + 8].source = Value; + regs[Idx + 16].source = Value; + return; + } + if (Idx >= 4 && Idx <= 7) + { + regs[Idx].source = Value; + regs[Idx + 4].source = Value; + regs[Idx + 12].source = Value; + return; + } + if (Idx >= 8 && Idx <= 11) + { + regs[Idx - 8].source = Value; + regs[Idx - 4].source = Value; + regs[Idx].source = Value; + regs[Idx + 8].source = Value; + return; + } + if (Idx >= 12 && Idx <= 15) + { + regs[Idx].source = Value; + regs[Idx + 8].source = Value; + return; + } +} +//--------------------------------------------------------------------------- +void __fastcall SetRegisterType(PRINFO regs, int Idx, String Value) +{ + if (Idx >= 16 && Idx <= 19) + { + regs[Idx - 16].type = Value; + regs[Idx - 12].type = Value; + regs[Idx - 8].type = Value; + regs[Idx].type = Value; + return; + } + if (Idx >= 20 && Idx <= 23) + { + regs[Idx - 8].type = Value; + regs[Idx].type = Value; + return; + } + if (Idx >= 0 && Idx <= 3) + { + regs[Idx].type = Value; + regs[Idx + 8].type = Value; + regs[Idx + 16].type = Value; + return; + } + if (Idx >= 4 && Idx <= 7) + { + regs[Idx].type = Value; + regs[Idx + 4].type = Value; + regs[Idx + 12].type = Value; + return; + } + if (Idx >= 8 && Idx <= 11) + { + regs[Idx - 8].type = Value; + regs[Idx - 4].type = Value; + regs[Idx].type = Value; + regs[Idx + 8].type = Value; + return; + } + if (Idx >= 12 && Idx <= 15) + { + regs[Idx].type = Value; + regs[Idx + 8].type = Value; + return; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType) +{ + //saved context + TList *sctx = new TList; + for (int n = 0; n < 3; n++) + { + if (!AnalyzeProc2(fromAdr, addArg, AnalyzeRetType, sctx)) break; + } + //delete sctx + CleanupList(sctx); +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType, TList *sctx) +{ + BYTE op, b1, b2; + char source; + bool reset, bpBased, vmt, fContinue = false; + WORD bpBase; + int n, num, instrLen, instrLen1, instrLen2, _ap, _procSize; + int reg1Idx, reg2Idx; + int sp = -1, fromIdx = -1; //fromIdx - index of register in instruction mov eax,reg (for processing call @IsClass) + DWORD b; + int fromPos, curPos, Pos; + DWORD curAdr; + DWORD lastMovAdr = 0; + DWORD procAdr, Val, Adr, Adr1; + DWORD reg, varAdr, classAdr, vmtAdr, lastAdr = 0; + PInfoRec recN, recN1; + PLOCALINFO locInfo; + PARGINFO argInfo; + PFIELDINFO fInfo = 0; + PRCONTEXT rinfo; + RINFO rtmp; + String comment, typeName, className = "", varName, varType; + String _eax_Type, _edx_Type, _ecx_Type, sType; + RINFO registers[32]; + RINFO stack[256]; + DISINFO DisInfo, DisInfo1; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return false; + if (IsFlagSet(cfPass2, fromPos)) return false; + if (IsFlagSet(cfEmbedded, fromPos)) return false; + if (IsFlagSet(cfExport, fromPos)) return false; + + //b1 = Code[fromPos]; + //b2 = Code[fromPos + 1]; + //if (!b1 && !b2) return false; + + //Import - return ret type of function + if (IsFlagSet(cfImport, fromPos)) return false; + recN = GetInfoRec(fromAdr); + + //if recN = 0 (Interface Methods!!!) then return + if (!recN || !recN->procInfo) return false; + + //Procedure from Knowledge Base not analyzed + if (recN && recN->kbIdx != -1) return false; + + //if (!IsFlagSet(cfPass1, fromPos)) + //??? + + SetFlag(cfProcStart | cfPass2, fromPos); + + //If function name contains class name get it + className = ExtractClassName(recN->GetName()); + bpBased = (recN->procInfo->flags & PF_BPBASED); + bpBase = (recN->procInfo->bpBase); + + rtmp.result = 0; rtmp.source = 0; rtmp.value = 0; rtmp.type = ""; + for (n = 0; n < 32; n++) registers[n] = rtmp; + + //Get args + _eax_Type = _edx_Type = _ecx_Type = ""; + BYTE callKind = recN->procInfo->flags & 7; + if (recN->procInfo->args && !callKind) + { + for (n = 0; n < recN->procInfo->args->Count; n++) + { + PARGINFO argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + if (argInfo->Ndx == 0) + { + if (className != "") + registers[16].type = className; + else + registers[16].type = argInfo->TypeDef; + _eax_Type = registers[16].type; + //var + if (argInfo->Tag == 0x22) registers[16].source = 'v'; + continue; + } + if (argInfo->Ndx == 1) + { + registers[18].type = argInfo->TypeDef; + _edx_Type = registers[18].type; + //var + if (argInfo->Tag == 0x22) registers[18].source = 'v'; + continue; + } + if (argInfo->Ndx == 2) + { + registers[17].type = argInfo->TypeDef; + _ecx_Type = registers[17].type; + //var + if (argInfo->Tag == 0x22) registers[17].source = 'v'; + continue; + } + break; + } + } + else if (className != "") + { + registers[16].type = className; + } + + _procSize = GetProcSize(fromAdr); + curPos = fromPos; curAdr = fromAdr; + + while (1) + { + if (curAdr >= CodeBase + TotalSize) break; + //Skip exception table + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + curPos += 4 + 8*num; curAdr += 4 + 8*num; + continue; + } + + b1 = Code[curPos]; + b2 = Code[curPos + 1]; + if (!b1 && !b2 && !lastAdr) break; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) break; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + + op = Disasm.GetOp(DisInfo.Mnem); + //Code + SetFlags(cfCode, curPos, instrLen); + //Instruction begin + SetFlag(cfInstruction, curPos); + + if (curAdr >= lastAdr) lastAdr = 0; + + if (op == OP_JMP) + { + if (curAdr == fromAdr) break; + if (DisInfo.OpType[0] == otMEM) + { + if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) break; + } + if (DisInfo.OpType[0] == otIMM) + { + Adr = DisInfo.Immediate; + if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) break; + if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) break; + if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) break; + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + if (DisInfo.Ret) + { + //End of proc + if (!lastAdr || curAdr == lastAdr) + { + if (AnalyzeRetType) + { + //Åñëè òèï ðåãèñòðà eax íå ïóñòîé, íàõîäèì áëèæàéøóþ ñâåðõó èíñòðóêöèþ åãî èíöèàëèçàöèè + if (registers[16].type != "") + { + for (Pos = curPos - 1; Pos >= fromPos; Pos--) + { + b = Flags[Pos]; + if ((b & cfInstruction) & !(b & cfSkip)) + { + Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo, 0); + //If branch - break + if (DisInfo.Branch) break; + //If call + //Other cases (call [reg+Ofs]; call [Adr]) need to add + if (DisInfo.Call) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + recN1 = GetInfoRec(Adr); + if (recN1 && recN1->procInfo/*recN1->kind == ikFunc*/) + { + typeName = recN1->type; + recN1 = GetInfoRec(fromAdr); + if (!(recN1->procInfo->flags & (PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->kind = ikFunc; + recN1->type = typeName; + } + } + } + } + else if (b & cfSetA) + { + recN1 = GetInfoRec(fromAdr); + if (!(recN1->procInfo->flags & (PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->kind = ikFunc; + recN1->type = registers[16].type; + } + } + } + } + } + } + break; + } + if (!IsFlagSet(cfSkip, curPos)) sp = -1; + } + + //cfBracket + if (IsFlagSet(cfBracket, curPos)) + { + if (op == OP_PUSH && sp < 255) + { + reg1Idx = DisInfo.OpRegIdx[0]; + sp++; + stack[sp] = registers[reg1Idx]; + } + else if (op == OP_POP && sp >= 0) + { + reg1Idx = DisInfo.OpRegIdx[0]; + registers[reg1Idx] = stack[sp]; + sp--; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + //Ïðîâåðèì, íå ïîïàë ëè âíóòðü èíñòðóêöèè Fixup èëè ThreadVar + bool NameInside = false; + for (int k = 1; k < instrLen; k++) + { + if (Infos[curPos + k]) + { + NameInside = true; + break; + } + } + + reset = ((op & OP_RESET) != 0); + + if (op == OP_MOV) lastMovAdr = DisInfo.Offset; + + //If loc then try get context + if (curAdr != fromAdr && IsFlagSet(cfLoc, curPos)) + { + rinfo = GetCtx(sctx, curAdr); + if (rinfo) + { + sp = rinfo->sp; + for (n = 0; n < 32; n++) registers[n] = rinfo->registers[n]; + } + //context not found - set flag to continue on the next step + else + { + fContinue = true; + } + } + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + if (!IsValidCodeAdr(DisInfo.Offset)) break; + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Àäðåñ òàáëèöû - ïîñëåäíèå 4 áàéòà èíñòðóêöèè + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Àíàëèçèðóåì ïðîìåæóòîê íà ïðåäìåò òàáëèöû cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //Åñëè åñòü cTblAdr, ïðîïóñêàåì ýòó òàáëèöó + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + Pos += CNum; Adr += CNum; + } + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + //Save context + if (!GetCtx(sctx, Adr1)) + { + rinfo = new RCONTEXT; + rinfo->sp = sp; + rinfo->adr = Adr1; + for (n = 0; n < 32; n++) rinfo->registers[n] = registers[n]; + sctx->Add((void*)rinfo); + } + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0 && Pos - NPos < MAX_DISASSEMBLE) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN = GetInfoRec(DisInfo.Immediate); + if (recN) + { + if (recN->SameName("@HandleFinally")) + { + //jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Adr = *((DWORD*)(Code + Pos)); Pos += 4; + if (IsValidImageAdr(Adr)) + { + recN1 = GetInfoRec(Adr); + if (recN1 && recN1->kind == ikVMT) className = recN1->GetName(); + } + //dd offset ExceptionProc + procAdr = *((DWORD*)(Code + Pos)); Pos += 4; + if (IsValidImageAdr(procAdr)) + { + //Save context + if (!GetCtx(sctx, procAdr)) + { + rinfo = new RCONTEXT; + rinfo->sp = sp; + rinfo->adr = procAdr; + for (n = 0; n < 32; n++) rinfo->registers[n] = registers[n]; + //eax + rinfo->registers[16].value = GetClassAdr(className); + rinfo->registers[16].type = className; + + sctx->Add((void*)rinfo); + } + } + } + } + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + } + //branch + if (DisInfo.Branch) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + _ap = Adr2Pos(Adr); + //SetFlag(cfLoc, _ap); + //recN1 = GetInfoRec(Adr); + //if (!recN1) recN1 = new InfoRec(_ap, ikUnknown); + //recN1->AddXref('C', fromAdr, curAdr - fromAdr); + //Save context + if (!GetCtx(sctx, Adr)) + { + rinfo = new RCONTEXT; + rinfo->sp = sp; + rinfo->adr = Adr; + for (n = 0; n < 32; n++) rinfo->registers[n] = registers[n]; + sctx->Add((void*)rinfo); + } + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + if (registers[16].type != "" && registers[16].type[1] == '#') + { + DWORD dd = *((DWORD*)(registers[16].type.c_str())); + //Åñëè áûë âûçîâ ôóíêöèè @GetTls, ñìîòðèì ñëåä. èíñòðóêöèþ âèäà [eax+N] + if (dd == 'SLT#') + { + //Åñëè íåò âíóòðåííåãî èìåíè (Fixup, ThreadVar) + if (!NameInside) + { + //Destination (GlobalLists := TList.Create) + //Source (GlobalLists.Add) + if ((DisInfo.OpType[0] == otMEM || DisInfo.OpType[1] == otMEM) && DisInfo.BaseReg == 16) + { + _ap = Adr2Pos(curAdr); assert(_ap >= 0); + recN1 = GetInfoRec(curAdr + 1); + if (!recN1) recN1 = new InfoRec(_ap + 1, ikThreadVar); + if (!recN1->HasName()) recN1->SetName(String("threadvar_") + DisInfo.Offset); + } + } + SetRegisterValue(registers, 16, 0xFFFFFFFF); + registers[16].type = ""; + curPos += instrLen; curAdr += instrLen; + continue; + } + } + //Call + if (DisInfo.Call) + { + Adr = DisInfo.Immediate; + if (IsValidImageAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN && recN->procInfo) + { + int retBytes = (int)recN->procInfo->retBytes; + if (retBytes != -1 && sp >= retBytes) + sp -= retBytes; + else + sp = -1; + + //for constructor type is in eax + if (recN->kind == ikConstructor) + { + //Åñëè dl = 1, ðåãèñòð eax ïîñëå âûçîâà èñïîëüçóåòñÿ + if (registers[2].value == 1) + { + classAdr = GetClassAdr(registers[16].type); + if (IsValidImageAdr(classAdr)) + { + //Add xref to vmt info + recN1 = GetInfoRec(classAdr); + recN1->AddXref('D', Adr, 0); + + comment = registers[16].type + ".Create"; + AddPicode(curPos, OP_CALL, comment, 0); + AnalyzeTypes(fromAdr, curPos, Adr, registers); + } + } + SetFlag(cfSetA, curPos); + } + else + { + //Found @Halt0 - exit + if (recN->SameName("@Halt0") && fromAdr == EP && !lastAdr) break; + + DWORD dynAdr; + if (recN->SameName("@ClassCreate")) + { + SetRegisterType(registers, 16, className); + SetFlag(cfSetA, curPos); + } + else if (recN->SameName("@CallDynaInst") || + recN->SameName("@CallDynaClass")) + { + if (DelphiVersion <= 5) + comment = GetDynaInfo(GetClassAdr(registers[16].type), registers[11].value, &dynAdr); //bx + else + comment = GetDynaInfo(GetClassAdr(registers[16].type), registers[14].value, &dynAdr); //si + AddPicode(curPos, OP_CALL, comment, dynAdr); + SetRegisterType(registers, 16, ""); + } + else if (recN->SameName("@FindDynaInst") || + recN->SameName("@FindDynaClass")) + { + comment = GetDynaInfo(GetClassAdr(registers[16].type), registers[10].value, &dynAdr); //dx + AddPicode(curPos, OP_CALL, comment, dynAdr); + SetRegisterType(registers, 16, ""); + } + //@XStrArrayClr + else if (recN->SameName("@LStrArrayClr") || recN->SameName("@WStrArrayClr") || recN->SameName("@UStrArrayClr")) + { + DWORD arrAdr = registers[16].value; + int cnt = registers[18].value; + //Direct address??? + if (IsValidImageAdr(arrAdr)) + { + } + //Local vars + else if ((registers[16].source & 0xDF) == 'L') + { + recN1 = GetInfoRec(fromAdr); + int aofs = registers[16].value; + for (int aa = 0; aa < cnt; aa++, aofs += 4) + { + if (recN->SameName("@LStrArrayClr")) + recN1->procInfo->AddLocal(aofs, 4, "", "AnsiString"); + else if (recN->SameName("@WStrArrayClr")) + recN1->procInfo->AddLocal(aofs, 4, "", "WideString"); + else if (recN->SameName("@UStrArrayClr")) + recN1->procInfo->AddLocal(aofs, 4, "", "UString"); + } + } + SetRegisterType(registers, 16, ""); + } + //@TryFinallyExit + else if (recN->SameName("@TryFinallyExit")) + { + //Find first jxxx + for (Pos = curPos - 1; Pos >= fromPos; Pos--) + { + b = Flags[Pos]; + if (b & cfInstruction) + { + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo, 0); + if (DisInfo.Conditional) break; + SetFlags(cfSkip | cfFinallyExit, Pos, instrLen1); + } + } + //@TryFinallyExit + jmp XXXXXXXX + instrLen += Disasm.Disassemble(Code + curPos + instrLen, (__int64)(Pos2Adr(curPos) + instrLen), &DisInfo, 0); + SetFlags(cfSkip | cfFinallyExit, curPos, instrLen); + } + else + { + String retType = AnalyzeTypes(fromAdr, curPos, Adr, registers); + recN1 = GetInfoRec(fromAdr); + for (int mm = 16; mm <= 18; mm++) + { + if (registers[mm].result == 1) + { + if ((registers[mm].source & 0xDF) == 'L') + { + recN1->procInfo->AddLocal((int)registers[mm].value, 4, "", registers[mm].type); + } + else if ((registers[mm].source & 0xDF) == 'A') + recN1->procInfo->AddArg(0x21, (int)registers[mm].value, 4, "", registers[mm].type); + } + } + SetRegisterType(registers, 16, retType); + } + } + } + else + { + sp = -1; + SetRegisterType(registers, 16, ""); + } + } + //call Memory + else if (DisInfo.OpType[0] == otMEM && DisInfo.IndxReg == -1) + { + sp = -1; + //call [Offset] + if (DisInfo.BaseReg == -1) + { + } + //call [BaseReg + Offset] + else + { + classAdr = registers[DisInfo.BaseReg].value; + SetRegisterType(registers, 16, ""); + if (IsValidCodeAdr(classAdr) && registers[DisInfo.BaseReg].source == 'V') + { + recN = GetInfoRec(classAdr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + for (int mm = 0; mm < recN->vmtInfo->methods->Count; mm++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[mm]; + if (recM->kind == 'V' && recM->id == (int)DisInfo.Offset) + { + recN1 = GetInfoRec(recM->address); + + if (recM->name != "") + comment = recM->name; + else + { + if (recN1->HasName()) + comment = recN1->GetName(); + else + comment = GetClsName(classAdr) + ".sub_" + Val2Str8(recM->address); + } + AddPicode(curPos, OP_CALL, comment, recM->address); + + recN1->AddXref('V', fromAdr, curAdr - fromAdr); + if (recN1->kind == ikFunc) SetRegisterType(registers, 16, recN1->type); + break; + } + } + } + registers[DisInfo.BaseReg].source = 0; + } + else + { + int callOfs = DisInfo.Offset; + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (typeName != "" && callOfs > 0) + { + Pos = GetNearestUpInstruction(curPos, fromPos, 1); Adr = Pos2Adr(Pos); + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + if (DisInfo.Offset == callOfs + 4) + { + fInfo = GetField(typeName, callOfs, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (fInfo->Name != "") AddPicode(curPos, OP_CALL, typeName + "." + fInfo->Name, 0); + if (vmt) + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + else + delete fInfo; + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, callOfs, -1, "", ""); + if (fInfo) AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + } + } + } + } + } + } + SetRegisterSource(registers, 16, 0); + SetRegisterSource(registers, 17, 0); + SetRegisterSource(registers, 18, 0); + SetRegisterValue(registers, 16, 0xFFFFFFFF); + curPos += instrLen; curAdr += instrLen; + continue; + } + sType = String(DisInfo.sSize); + //floating point operations + if (DisInfo.Float) + { + float singleVal; + long double extendedVal; + String fVal = ""; + + switch (DisInfo.OpSize) + { + case 4: + sType = "Single"; + break; + //Double or Comp??? + case 8: + sType = "Double"; + break; + case 10: + sType = "Extended"; + break; + default: + sType = "Float"; + break; + } + + Adr = DisInfo.Offset; + _ap = Adr2Pos(Adr); + //fxxx [Adr] + if (DisInfo.BaseReg == -1 && DisInfo.IndxReg == -1) + { + if (IsValidImageAdr(Adr)) + { + if (_ap >= 0) + { + switch (DisInfo.OpSize) + { + case 4: + singleVal = 0; memmove((void*)&singleVal, Code + _ap, 4); + fVal = FloatToStr(singleVal); + break; + //Double or Comp??? + case 8: + break; + case 10: + try + { + extendedVal = 0; memmove((void*)&extendedVal, Code + _ap, 10); + fVal = FloatToStr(extendedVal); + } + catch (Exception &E) + { + fVal = "Impossible!"; + } + break; + } + SetFlags(cfData, _ap, DisInfo.OpSize); + + recN = GetInfoRec(Adr); + if (!recN) recN = new InfoRec(_ap, ikData); + if (!recN->HasName()) recN->SetName(fVal); + if (recN->type == "") recN->type = sType; + if (!IsValidCodeAdr(Adr)) recN->AddXref('D', fromAdr, curAdr - fromAdr); + } + else + { + recN = AddToBSSInfos(Adr, MakeGvarName(Adr), sType); + if (recN) recN->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + else if (DisInfo.BaseReg != -1) + { + //fxxxx [BaseReg + Offset] + if (DisInfo.IndxReg == -1) + { + //fxxxx [ebp - Offset] + if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) + { + recN1 = GetInfoRec(fromAdr); + recN1->procInfo->AddLocal((int)DisInfo.Offset, DisInfo.OpSize, "", sType); + } + //fxxx [esp + Offset] + else if (DisInfo.BaseReg == 20) + { + dummy = 1; + } + else + { + //fxxxx [BaseReg] + if (!DisInfo.Offset) + { + varAdr = registers[DisInfo.BaseReg].value; + if (IsValidImageAdr(varAdr)) + { + _ap = Adr2Pos(varAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(varAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, varAdr, curAdr); + recN1->type = sType; + if (!IsValidCodeAdr(varAdr)) recN1->AddXref('D', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(varAdr, MakeGvarName(varAdr), sType); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + //fxxxx [BaseReg + Offset] + else if ((int)DisInfo.Offset > 0) + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (typeName != "") + { + fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (vmt) + { + if (CanReplace(fInfo->Type, sType)) fInfo->Type = sType; + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + } + else + delete fInfo; + //if (vmtAdr) typeName = GetClsName(vmtAdr); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); + if (fInfo) + { + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + } + } + } + //fxxxx [BaseReg - Offset] + else + { + } + } + } + //fxxxx [BaseReg + IndxReg*Scale + Offset] + else + { + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + //No operands + if (DisInfo.OpNum == 0) + { + //cdq + if (op == OP_CDQ) + { + SetRegisterSource(registers, 16, 'I'); + SetRegisterValue(registers, 16, 0xFFFFFFFF); + SetRegisterType(registers, 16, "Integer"); + SetRegisterSource(registers, 18, 'I'); + SetRegisterValue(registers, 18, 0xFFFFFFFF); + SetRegisterType(registers, 18, "Integer"); + } + } + //1 operand + else if (DisInfo.OpNum == 1) + { + //op Imm + if (DisInfo.OpType[0] == otIMM) + { + if (IsValidImageAdr(DisInfo.Immediate)) + { + _ap = Adr2Pos(DisInfo.Immediate); + if (_ap >= 0) + { + recN1 = GetInfoRec(DisInfo.Immediate); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(DisInfo.Immediate, MakeGvarName(DisInfo.Immediate), ""); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + //op reg + else if (DisInfo.OpType[0] == otREG && op != OP_UNK && op != OP_PUSH) + { + reg1Idx = DisInfo.OpRegIdx[0]; + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + //op [BaseReg + Offset] + else if (DisInfo.OpType[0] == otMEM) + { + if (DisInfo.BaseReg != -1 && DisInfo.IndxReg == -1 && (int)DisInfo.Offset > 0) + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (typeName != "") + { + fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (vmt) + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + else + delete fInfo; + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); + if (fInfo) + { + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + } + } + } + if (op == OP_IMUL || op == OP_IDIV) + { + SetRegisterSource(registers, 16, 0); + SetRegisterValue(registers, 16, 0xFFFFFFFF); + SetRegisterType(registers, 16, "Integer"); + SetRegisterSource(registers, 18, 0); + SetRegisterValue(registers, 18, 0xFFFFFFFF); + SetRegisterType(registers, 18, "Integer"); + } + } + } + //2 or 3 operands + else if (DisInfo.OpNum >= 2) + { + if (op & OP_A2) + //if (op == OP_MOV || op == OP_CMP || op == OP_LEA || op == OP_XOR || op == OP_ADD || op == OP_SUB || + // op == OP_AND || op == OP_TEST || op == OP_XCHG || op == OP_IMUL || op == OP_IDIV || op == OP_OR || + // op == OP_BT || op == OP_BTC || op == OP_BTR || op == OP_BTS) + { + if (DisInfo.OpType[0] == otREG) //cop reg,... + { + reg1Idx = DisInfo.OpRegIdx[0]; + source = registers[reg1Idx].source; + SetRegisterSource(registers, reg1Idx, 0); + + if (DisInfo.OpType[1] == otIMM) //cop reg, Imm + { + if (reset) + { + typeName = TrimTypeName(registers[reg1Idx].type); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + + if (op == OP_ADD) + { + if (typeName != "" && source != 'v') + { + fInfo = GetField(typeName, (int)DisInfo.Immediate, &vmt, &vmtAdr, ""); + if (fInfo) + { + registers[reg1Idx].type = fInfo->Type; + if (vmt) + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + else + delete fInfo; + //if (vmtAdr) typeName = GetClsName(vmtAdr); + AddPicode(curPos, 0, typeName, DisInfo.Immediate); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Immediate, -1, "", ""); + if (fInfo) + { + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + AddPicode(curPos, 0, typeName, DisInfo.Immediate); + } + } + } + } + else + { + if (op == OP_MOV) SetRegisterValue(registers, reg1Idx, DisInfo.Immediate); + SetRegisterSource(registers, reg1Idx, 'I'); + if (IsValidImageAdr(DisInfo.Immediate)) + { + _ap = Adr2Pos(DisInfo.Immediate); + if (_ap >= 0) + { + recN1 = GetInfoRec(DisInfo.Immediate); + if (recN1) + { + SetRegisterType(registers, reg1Idx, recN1->type); + bool _addXref = false; + switch (recN1->kind) + { + case ikString: + SetRegisterType(registers, reg1Idx, "ShortString"); + _addXref = true; + break; + case ikLString: + SetRegisterType(registers, reg1Idx, "AnsiString"); + _addXref = true; + break; + case ikWString: + SetRegisterType(registers, reg1Idx, "WideString"); + _addXref = true; + break; + case ikCString: + SetRegisterType(registers, reg1Idx, "PAnsiChar"); + _addXref = true; + break; + case ikWCString: + SetRegisterType(registers, reg1Idx, "PWideChar"); + _addXref = true; + break; + case ikUString: + SetRegisterType(registers, reg1Idx, "UString"); + _addXref = true; + break; + } + if (_addXref) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + else + { + recN1 = AddToBSSInfos(DisInfo.Immediate, MakeGvarName(DisInfo.Immediate), ""); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + } + } + else if (DisInfo.OpType[1] == otREG) //cop reg, reg + { + reg2Idx = DisInfo.OpRegIdx[1]; + if (reset) + { + if (op == OP_MOV) + { + SetRegisterSource(registers, reg1Idx, registers[reg2Idx].source); + SetRegisterValue(registers, reg1Idx, registers[reg2Idx].value); + SetRegisterType(registers, reg1Idx, registers[reg2Idx].type); + if (reg1Idx == 16) fromIdx = reg2Idx; + } + else if (op == OP_XOR) + { + SetRegisterValue(registers, reg1Idx, registers[reg1Idx].value ^ registers[reg2Idx].value); + SetRegisterType(registers, reg1Idx, ""); + } + else if (op == OP_XCHG) + { + rtmp = registers[reg1Idx]; registers[reg1Idx] = registers[reg2Idx]; registers[reg2Idx] = rtmp; + } + else if (op == OP_IMUL || op == OP_IDIV) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + if (reg1Idx != reg2Idx) + { + SetRegisterSource(registers, reg2Idx, 0); + SetRegisterValue(registers, reg2Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg2Idx, "Integer"); + } + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + } + else if (DisInfo.OpType[1] == otMEM) //cop reg, Memory + { + if (DisInfo.BaseReg == -1) + { + if (DisInfo.IndxReg == -1) //cop reg, [Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + Adr = DisInfo.Offset; + if (IsValidImageAdr(Adr)) + { + _ap = Adr2Pos(Adr); + if (_ap >= 0) + { + recN = GetInfoRec(Adr); + if (recN) + { + MakeGvar(recN, Adr, curAdr); + if (recN->kind == ikVMT) + { + if (reset) + { + SetRegisterType(registers, reg1Idx, recN->GetName()); + SetRegisterValue(registers, reg1Idx, Adr - cVmtSelfPtr); + } + } + else + { + if (reset) registers[reg1Idx].type = recN->type; + if (reg1Idx < 24) + { + if (reg1Idx >= 16) + { + if (IsFlagSet(cfImport, _ap)) + { + recN1 = GetInfoRec(Adr); + AddPicode(curPos, OP_COMMENT, recN1->GetName(), 0); + } + else if (!IsFlagSet(cfRTTI, _ap)) + { + Val = *((DWORD*)(Code + _ap)); + if (reset) SetRegisterValue(registers, reg1Idx, Val); + if (IsValidImageAdr(Val)) + { + _ap = Adr2Pos(Val); + if (_ap >= 0) + { + recN1 = GetInfoRec(Val); + if (recN1) + { + MakeGvar(recN1, Val, curAdr); + varName = recN1->GetName(); + if (varName != "") recN->SetName("^" + varName); + if (recN->type != "") registers[reg1Idx].type = recN->type; + varType = recN1->type; + if (varType != "") + { + recN->type = varType; + registers[reg1Idx].type = varType; + } + } + else + { + recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, Val, curAdr); + varName = recN1->GetName(); + if (varName != "") recN->SetName("^" + varName); + if (recN->type != "") registers[reg1Idx].type = recN->type; + } + if (recN) recN->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + if (recN->HasName()) + recN1 = AddToBSSInfos(Val, recN->GetName(), recN->type); + else + recN1 = AddToBSSInfos(Val, MakeGvarName(Val), recN->type); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + else + { + AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); + SetFlags(cfData, _ap, 4); + } + } + } + else + { + if (reg1Idx <= 7) + { + Val = *(Code + _ap); + } + else if (reg1Idx <= 15) + { + Val = *((WORD*)(Code + _ap)); + } + AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); + SetFlags(cfData, _ap, 4); + } + } + } + } + else + { + recN = new InfoRec(_ap, ikData); + MakeGvar(recN, Adr, curAdr); + if (reg1Idx < 24) + { + if (reg1Idx >= 16) + { + Val = *((DWORD*)(Code + _ap)); + if (reset) SetRegisterValue(registers, reg1Idx, Val); + if (IsValidImageAdr(Val)) + { + _ap = Adr2Pos(Val); + if (_ap >= 0) + { + recN->kind = ikPointer; + recN1 = GetInfoRec(Val); + if (recN1) + { + MakeGvar(recN1, Val, curAdr); + varName = recN1->GetName(); + if (varName != "" && (recN1->kind == ikLString || recN1->kind == ikWString || recN1->kind == ikUString)) + varName = "\"" + varName + "\""; + if (varName != "") recN->SetName("^" + varName); + if (recN->type != "") registers[reg1Idx].type = recN->type; + varType = recN1->type; + if (varType != "") + { + recN->type = varType; + registers[reg1Idx].type = varType; + } + } + else + { + recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, Val, curAdr); + varName = recN1->GetName(); + if (varName != "" && (recN1->kind == ikLString || recN1->kind == ikWString || recN1->kind == ikUString)) + varName = "\"" + varName + "\""; + if (varName != "") recN->SetName("^" + varName); + if (recN->type != "") registers[reg1Idx].type = recN->type; + } + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(Val, MakeGvarName(Val), ""); + if (recN1) + { + recN1->AddXref('C', fromAdr, curAdr - fromAdr); + if (recN->type != "") recN->type = recN1->type; + } + } + } + else + { + AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); + SetFlags(cfData, _ap, 4); + } + } + else + { + if (reg1Idx <= 7) + { + Val = *(Code + _ap); + } + else if (reg1Idx <= 15) + { + Val = *((WORD*)(Code + _ap)); + } + AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); + SetFlags(cfData, _ap, 4); + } + } + } + } + else + { + recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + + } + } + else //cop reg, [Offset + IndxReg*Scale] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + + Adr = DisInfo.Offset; + if (IsValidImageAdr(Adr)) + { + _ap = Adr2Pos(Adr); + if (_ap >= 0) + { + recN = GetInfoRec(Adr); + if (recN) + { + if (recN->kind == ikVMT) + typeName = recN->GetName(); + else + typeName = recN->type; + + if (reset) SetRegisterType(registers, reg1Idx, typeName); + if (!IsValidCodeAdr(Adr)) recN->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + else + { + recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + } + else + { + if (DisInfo.IndxReg == -1) + { + if (bpBased && DisInfo.BaseReg == 21) //cop reg, [ebp + Offset] + { + if ((int)DisInfo.Offset < 0) //cop reg, [ebp - Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterSource(registers, reg1Idx, (op == OP_LEA) ? 'L' : 'l'); + SetRegisterValue(registers, reg1Idx, DisInfo.Offset); + SetRegisterType(registers, reg1Idx, ""); + } + } + //xchg ecx, [ebp-4] (ecx = 0, [ebp-4] = _ecx_) + if ((int)DisInfo.Offset == -4 && reg1Idx == 17) + { + recN1 = GetInfoRec(fromAdr); + locInfo = recN1->procInfo->AddLocal((int)DisInfo.Offset, 4, "", ""); + SetRegisterType(registers, reg1Idx, _ecx_Type); + } + else + { + recN1 = GetInfoRec(fromAdr); + locInfo = recN1->procInfo->AddLocal((int)DisInfo.Offset, DisInfo.OpSize, "", ""); + //mov, xchg + if (op == OP_MOV || op == OP_XCHG) + { + SetRegisterType(registers, reg1Idx, locInfo->TypeDef); + } + else if (op == OP_LEA && locInfo->TypeDef != "") + { + SetRegisterType(registers, reg1Idx, locInfo->TypeDef); + } + } + } + else //cop reg, [ebp + Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + if (bpBased && addArg) + { + recN1 = GetInfoRec(fromAdr); + argInfo = recN1->procInfo->AddArg(0x21, DisInfo.Offset, 4, "", ""); + if (op == OP_MOV || op == OP_LEA || op == OP_XCHG) + { + SetRegisterSource(registers, reg1Idx, (op == OP_LEA) ? 'A' : 'a'); + SetRegisterValue(registers, reg1Idx, DisInfo.Offset); + SetRegisterType(registers, reg1Idx, argInfo->TypeDef); + } + } + } + } + else if (DisInfo.BaseReg == 20) //cop reg, [esp + Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + } + else //cop reg, [BaseReg + Offset] + { + if (!DisInfo.Offset) //cop reg, [BaseReg] + { + Adr = registers[DisInfo.BaseReg].value; + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + + if (typeName != "") + { + if (typeName[1] == '^') typeName = typeName.SubString(2, typeName.Length() - 1); + SetRegisterValue(registers, reg1Idx, GetClassAdr(typeName)); + SetRegisterType(registers, reg1Idx, typeName); //??? + SetRegisterSource(registers, reg1Idx, 'V'); //Virtual table base (for calls processing) + } + if (IsValidImageAdr(Adr)) + { + _ap = Adr2Pos(Adr); + if (_ap >= 0) + { + recN = GetInfoRec(Adr); + if (recN) + { + if (recN->kind == ikVMT) + { + SetRegisterType(registers, reg1Idx, recN->GetName()); + SetRegisterValue(registers, reg1Idx, Adr - cVmtSelfPtr); + } + else + { + SetRegisterType(registers, reg1Idx, recN->type); + if (recN->type != "") + SetRegisterValue(registers, reg1Idx, GetClassAdr(recN->type)); + } + } + } + else + { + AddToBSSInfos(Adr, MakeGvarName(Adr), ""); + } + } + } + } + else if ((int)DisInfo.Offset > 0) //cop reg, [BaseReg + Offset] + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); sType = "Integer"; + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + if (typeName != "") + { + fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (op == OP_MOV || op == OP_XCHG) + { + registers[reg1Idx].type = fInfo->Type; + } + if (vmt) + { + if (CanReplace(fInfo->Type, sType)) fInfo->Type = sType; + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + } + else + delete fInfo; + //if (vmtAdr) typeName = GetClsName(vmtAdr); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); + if (fInfo) + { + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + } + } + } + else //cop reg, [BaseReg - Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + } + } + } + else //cop reg, [BaseReg + IndxReg*Scale + Offset] + { + if (DisInfo.BaseReg == 21) //cop reg, [ebp + IndxReg*Scale + Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + } + else if (DisInfo.BaseReg == 20) //cop reg, [esp + IndxReg*Scale + Offset] + { + if (reset) + { + if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + } + else //cop reg, [BaseReg + IndxReg*Scale + Offset] + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (reset) + { + if (op == OP_LEA) + { + //BaseReg - points to class + if (typeName != "") + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + //Else - general arifmetics + else + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + } + else if (op == OP_IMUL) + { + SetRegisterSource(registers, reg1Idx, 0); + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, "Integer"); + } + else + { + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + SetRegisterType(registers, reg1Idx, ""); + } + } + } + } + } + } + } + //cop Mem,... + else + { + //cop Mem, Imm + if (DisInfo.OpType[1] == otIMM) + { + //cop [Offset], Imm + if (DisInfo.BaseReg == -1 && DisInfo.IndxReg == -1) + { + Adr = DisInfo.Offset; + if (IsValidImageAdr(Adr)) + { + _ap = Adr2Pos(Adr); + if (_ap >= 0) + { + recN1 = GetInfoRec(Adr); + if (!recN1) recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, Adr, curAdr); + if (!IsValidCodeAdr(Adr)) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + //cop [BaseReg + IndxReg*Scale + Offset], Imm + else if (DisInfo.BaseReg != -1) + { + //cop [BaseReg + Offset], Imm + if (DisInfo.IndxReg == -1) + { + //cop [ebp - Offset], Imm + if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) + { + recN1 = GetInfoRec(fromAdr); + recN1->procInfo->AddLocal((int)DisInfo.Offset, DisInfo.OpSize, "", ""); + } + //cop [esp], Imm + else if (DisInfo.BaseReg == 20) + { + dummy = 1; + } + //other registers + else + { + //cop [BaseReg], Imm + if (!DisInfo.Offset) + { + Adr = registers[DisInfo.BaseReg].value; + if (IsValidImageAdr(Adr)) + { + _ap = Adr2Pos(Adr); + if (_ap >= 0) + { + recN = GetInfoRec(Adr); + if (!recN) recN = new InfoRec(_ap, ikData); + MakeGvar(recN, Adr, curAdr); + if (!IsValidCodeAdr(Adr)) recN->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + //cop [BaseReg + Offset], Imm + else if ((int)DisInfo.Offset > 0) + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (typeName != "") + { + fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (vmt) + { + if (op != OP_CMP && op != OP_TEST) + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); + else + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + } + else + delete fInfo; + //if (vmtAdr) typeName = GetClsName(vmtAdr); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); + if (fInfo) + { + if (op != OP_CMP && op != OP_TEST) + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); + else + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + } + } + } + //cop [BaseReg - Offset], Imm + else + { + } + } + } + //cop [BaseReg + IndxReg*Scale + Offset], Imm + else + { + } + } + //Other instructions + else + { + } + } + //cop Mem, reg + else if (DisInfo.OpType[1] == otREG) + { + reg2Idx = DisInfo.OpRegIdx[1]; + //op [Offset], reg + if (DisInfo.BaseReg == -1 && DisInfo.IndxReg == -1) + { + varAdr = DisInfo.Offset; + if (IsValidImageAdr(varAdr)) + { + _ap = Adr2Pos(varAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(varAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, varAdr, curAdr); + if (op == OP_MOV) + { + if (registers[reg2Idx].type != "") recN1->type = registers[reg2Idx].type; + } + if (!IsValidCodeAdr(varAdr)) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(varAdr, MakeGvarName(varAdr), registers[reg2Idx].type); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + } + //cop [BaseReg + IndxReg*Scale + Offset], reg + else if (DisInfo.BaseReg != -1) + { + if (DisInfo.IndxReg == -1) + { + //cop [ebp - Offset], reg + if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) + { + recN1 = GetInfoRec(fromAdr); + recN1->procInfo->AddLocal((int)DisInfo.Offset, 4, "", registers[reg2Idx].type); + } + //esp + else if (DisInfo.BaseReg == 20) + { + } + //other registers + else + { + //cop [BaseReg], reg + if (!DisInfo.Offset) + { + varAdr = registers[DisInfo.BaseReg].value; + if (IsValidImageAdr(varAdr)) + { + _ap = Adr2Pos(varAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(varAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, varAdr, curAdr); + if (recN1->type == "") recN1->type = registers[reg2Idx].type; + if (!IsValidCodeAdr(varAdr)) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + else + { + recN1 = AddToBSSInfos(varAdr, MakeGvarName(varAdr), registers[reg2Idx].type); + if (recN1) recN1->AddXref('C', fromAdr, curAdr - fromAdr); + } + } + else + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (typeName != "") + { + if (registers[reg2Idx].type != "") sType = registers[reg2Idx].type; + fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (vmt) + { + if (CanReplace(fInfo->Type, sType)) fInfo->Type = sType; + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); + } + else + delete fInfo; + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); + if (fInfo) + { + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + } + } + } + } + //cop [BaseReg + Offset], reg + else if ((int)DisInfo.Offset > 0) + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + if (typeName != "") + { + if (registers[reg2Idx].type != "") sType = registers[reg2Idx].type; + fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + if (vmt) + { + if (CanReplace(fInfo->Type, sType)) fInfo->Type = sType; + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); + } + else + delete fInfo; + //if (vmtAdr) typeName = GetClsName(vmtAdr); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + else if (vmt) + { + fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); + if (fInfo) + { + AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); + AddPicode(curPos, 0, typeName, DisInfo.Offset); + } + } + } + } + //cop [BaseReg - Offset], reg + else + { + } + } + } + //cop [BaseReg + IndxReg*Scale + Offset], reg + else + { + //cop [BaseReg + IndxReg*Scale + Offset], reg + if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) + { + } + //esp + else if (DisInfo.BaseReg == 20) + { + } + //other registers + else + { + //[BaseReg] + if (!DisInfo.Offset) + { + } + //cop [BaseReg + IndxReg*Scale + Offset], reg + else if ((int)DisInfo.Offset > 0) + { + typeName = TrimTypeName(registers[DisInfo.BaseReg].type); + } + //cop [BaseReg - Offset], reg + else + { + } + } + } + } + //Other instructions + else + { + } + } + } + } + else if (op == OP_ADC || op == OP_SBB) + { + if (DisInfo.OpType[0] == otREG) + { + reg1Idx = DisInfo.OpRegIdx[0]; + SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + registers[reg1Idx].type = ""; + } + } + else if (op == OP_MUL || op == OP_DIV) + { + //Clear register eax + SetRegisterValue(registers, 16, 0xFFFFFFFF); + for (n = 0; n <=16; n += 4) + { + if (n == 12) continue; + registers[n].type = ""; + } + //Clear register edx + SetRegisterValue(registers, 18, 0xFFFFFFFF); + for (n = 2; n <= 18; n += 4) + { + if (n == 14) continue; + registers[n].type = ""; + } + } + else + { + if (DisInfo.OpType[0] == otREG) + { + reg1Idx = DisInfo.OpRegIdx[0]; + if ((registers[reg1Idx].source & 0xDF) != 'L') SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); + registers[reg1Idx].type = ""; + } + } + //SHL??? SHR??? + } + curPos += instrLen; curAdr += instrLen; + } + return fContinue; +} +//--------------------------------------------------------------------------- +String __fastcall TFMain_11011981::AnalyzeTypes(DWORD parentAdr, int callPos, DWORD callAdr, PRINFO registers) +{ + WORD codePage, elemSize = 1; + int n, wBytes, pos, pushn, itemPos, refcnt, len, regIdx; + int _idx, _ap, _kind, _size, _pos; + DWORD itemAdr, strAdr; + char *tmpBuf; + PInfoRec recN, recN1; + PARGINFO argInfo; + String typeDef, typeName, retName, _vs; + DISINFO _disInfo; + char buf[1024]; //for LoadStr function + + _ap = Adr2Pos(callAdr); + if (_ap < 0) return ""; + + retName = ""; + recN = GetInfoRec(callAdr); + //If procedure is skipped return + if (IsFlagSet(cfSkip, callPos)) + { + //@BeforeDestruction + if (recN->SameName("@BeforeDestruction")) return registers[16].type; + + return recN->type; + } + + //cdecl, stdcall + if (recN->procInfo->flags & 1) + { + if (!recN->procInfo->args || !recN->procInfo->args->Count) + { + return recN->type; + } + + for (pos = callPos, pushn = -1;; pos--) + { + if (!IsFlagSet(cfInstruction, pos)) continue; + if (IsFlagSet(cfProcStart, pos)) break; + //I cannot yet handle this situation + if (IsFlagSet(cfCall, pos) && pos != callPos) break; + if (IsFlagSet(cfPush, pos)) + { + pushn++; + if (pushn < recN->procInfo->args->Count) + { + Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + itemAdr = _disInfo.Immediate; + if (IsValidImageAdr(itemAdr)) + { + itemPos = Adr2Pos(itemAdr); + argInfo = (PARGINFO)recN->procInfo->args->Items[pushn]; + typeDef = argInfo->TypeDef; + + if (SameText(typeDef, "PAnsiChar") || SameText(typeDef, "PChar")) + { + if (itemPos >= 0) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + //var - use pointer + if (argInfo->Tag == 0x22) + { + strAdr = *((DWORD*)(Code + itemPos)); + if (!strAdr) + { + SetFlags(cfData, itemPos, 4); + MakeGvar(recN1, itemAdr, Pos2Adr(pos)); + if (typeDef != "") recN1->type = typeDef; + } + else + { + _ap = Adr2Pos(strAdr); + if (_ap >= 0) + { + len = strlen((char*)(Code + _ap)); + SetFlags(cfData, _ap, len + 1); + } + else if (_ap == -1) + { + recN1 = AddToBSSInfos(strAdr, MakeGvarName(strAdr), typeDef); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + } + //val + else if (argInfo->Tag == 0x21) + { + recN1->kind = ikCString; + len = strlen(Code + itemPos); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + recN1->SetName(TransformString(Code + itemPos, len)); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + SetFlags(cfData, itemPos, len + 1); + } + if (recN1) recN1->ScanUpItemAndAddRef(callPos, itemAdr, 'C', parentAdr); + } + else + { + recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + else if (SameText(typeDef, "PWideChar")) + { + if (itemPos) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + //var - use pointer + if (argInfo->Tag == 0x22) + { + strAdr = *((DWORD*)(Code + itemPos)); + if (!strAdr) + { + SetFlags(cfData, itemPos, 4); + MakeGvar(recN1, itemAdr, Pos2Adr(pos)); + if (typeDef != "") recN1->type = typeDef; + } + else + { + _ap = Adr2Pos(strAdr); + if (_ap >= 0) + { + len = wcslen((wchar_t*)(Code + Adr2Pos(strAdr))); + SetFlags(cfData, Adr2Pos(strAdr), 2*len + 1); + } + else if (_ap == -1) + { + recN1 = AddToBSSInfos(strAdr, MakeGvarName(strAdr), typeDef); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + } + //val + else if (argInfo->Tag == 0x21) + { + recN1->kind = ikWCString; + len = wcslen((wchar_t*)(Code + itemPos)); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + WideString wStr = WideString((wchar_t*)(Code + itemPos)); + int size = WideCharToMultiByte(CP_ACP, 0, wStr, len, 0, 0, 0, 0); + if (size) + { + tmpBuf = new char[size + 1]; + WideCharToMultiByte(CP_ACP, 0, wStr, len, (LPSTR)tmpBuf, size, 0, 0); + recN1->SetName(TransformString(tmpBuf, size)); + delete[] tmpBuf; + if (recN->SameName("GetProcAddress")) retName = recN1->GetName(); + } + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + SetFlags(cfData, itemPos, 2*len + 1); + } + recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + else if (SameText(typeDef, "TGUID")) + { + if (itemPos) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikGUID); + recN1->kind = ikGUID; + SetFlags(cfData, itemPos, 16); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + recN1->SetName(Guid2String(Code + itemPos)); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + } + if (pushn == recN->procInfo->args->Count - 1) break; + } + } + } + return recN->type; + } + if (recN->HasName()) + { + if (recN->SameName("LoadStr") || recN->SameName("FmtLoadStr") || recN->SameName("LoadResString")) + { + int ident = registers[16].value; //eax = string ID + if (ident != -1) + { + HINSTANCE hInst = LoadLibraryEx(SourceFile.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); + if (hInst) + { + int bytes = LoadString(hInst, (UINT)ident, buf, 1024); + if (bytes) AddPicode(callPos, OP_COMMENT, "'" + String(buf, bytes) + "'", 0); + FreeLibrary(hInst); + } + } + return ""; + } + if (recN->SameName("TApplication.CreateForm")) + { + DWORD vmtAdr = registers[18].value + cVmtSelfPtr; //edx + + DWORD refAdr = registers[17].value; //ecx + if (IsValidImageAdr(refAdr)) + { + typeName = GetClsName(vmtAdr); + _ap = Adr2Pos(refAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(refAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikData); + MakeGvar(recN1, refAdr, 0); + if (typeName != "") recN1->type = typeName; + } + else + { + _vs = Val2Str8(refAdr); + _idx = BSSInfos->IndexOf(_vs); + if (_idx != -1) + { + recN1 = (PInfoRec)BSSInfos->Objects[_idx]; + if (typeName != "") recN1->type = typeName; + } + } + } + return ""; + } + if (recN->SameName("@FinalizeRecord")) + { + DWORD recAdr = registers[16].value; //eax + DWORD recTypeAdr = registers[18].value; //edx + typeName = GetTypeName(recTypeAdr); + //Address given directly + if (IsValidImageAdr(recAdr)) + { + _ap = Adr2Pos(recAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(recAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikRecord); + MakeGvar(recN1, recAdr, 0); + if (typeName != "") recN1->type = typeName; + if (!IsValidCodeAdr(recAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(recAdr, MakeGvarName(recAdr), typeName); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + //Local variable + else if ((registers[16].source & 0xDF) == 'L') + { + if (registers[16].type == "" && typeName != "") registers[16].type = typeName; + registers[16].result = 1; + } + return ""; + } + if (recN->SameName("@DynArrayAddRef")) + { + DWORD arrayAdr = registers[16].value; //eax + //Address given directly + if (IsValidImageAdr(arrayAdr)) + { + _ap = Adr2Pos(arrayAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(arrayAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikDynArray); + MakeGvar(recN1, arrayAdr, 0); + if (!IsValidCodeAdr(arrayAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), ""); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + //Local variable + else if ((registers[16].source & 0xDF) == 'L') + { + if (registers[16].type == "") registers[16].type = "array of ?"; + registers[16].result = 1; + } + return ""; + } + if (recN->SameName("DynArrayClear") || + recN->SameName("@DynArrayClear") || + recN->SameName("DynArraySetLength") || + recN->SameName("@DynArraySetLength")) + { + DWORD arrayAdr = registers[16].value; //eax + DWORD elTypeAdr = registers[18].value; //edx + typeName = GetTypeName(elTypeAdr); + //Address given directly + if (IsValidImageAdr(arrayAdr)) + { + _ap = Adr2Pos(arrayAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(arrayAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikDynArray); + MakeGvar(recN1, arrayAdr, 0); + if (recN1->type == "" && typeName != "") recN1->type = typeName; + if (!IsValidCodeAdr(arrayAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), typeName); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + //Local variable + else if ((registers[16].source & 0xDF) == 'L') + { + if (registers[16].type == "" && typeName != "") registers[16].type = typeName; + registers[16].result = 1; + } + return ""; + } + if (recN->SameName("@DynArrayCopy")) + { + DWORD arrayAdr = registers[16].value; //eax + DWORD elTypeAdr = registers[18].value; //edx + DWORD dstArrayAdr = registers[17].value; //ecx + typeName = GetTypeName(elTypeAdr); + //Address given directly + if (IsValidImageAdr(arrayAdr)) + { + _ap = Adr2Pos(arrayAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(arrayAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikDynArray); + MakeGvar(recN1, arrayAdr, 0); + if (typeName != "") recN1->type = typeName; + if (!IsValidCodeAdr(arrayAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), typeName); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + //Local variable + else if ((registers[16].source & 0xDF) == 'L') + { + if (registers[16].type == "" && typeName != "") registers[16].type = typeName; + registers[16].result = 1; + } + //Address given directly + if (IsValidImageAdr(dstArrayAdr)) + { + _ap = Adr2Pos(dstArrayAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(dstArrayAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikDynArray); + MakeGvar(recN1, dstArrayAdr, 0); + if (typeName != "") recN1->type = typeName; + if (!IsValidCodeAdr(dstArrayAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(dstArrayAdr, MakeGvarName(dstArrayAdr), typeName); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + //Local variable + else if ((registers[17].source & 0xDF) == 'L') + { + if (registers[17].type == "" && typeName != "") registers[17].type = typeName; + registers[17].result = 1; + } + return ""; + } + if (recN->SameName("@IntfClear")) + { + DWORD intfAdr = registers[16].value; //eax + + if (IsValidImageAdr(intfAdr)) + { + _ap = Adr2Pos(intfAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(intfAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikInterface); + MakeGvar(recN1, intfAdr, 0); + recN1->type = "IInterface"; + if (!IsValidCodeAdr(intfAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(intfAdr, MakeGvarName(intfAdr), "IInterface"); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + return ""; + } + if (recN->SameName("@FinalizeArray")) + { + DWORD arrayAdr = registers[16].value; //eax + int elNum = registers[17].value; //ecx + DWORD elTypeAdr = registers[18].value; //edx + + if (IsValidImageAdr(arrayAdr)) + { + typeName = "array[" + String(elNum) + "] of " + GetTypeName(elTypeAdr); + _ap = Adr2Pos(arrayAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(arrayAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikArray); + MakeGvar(recN1, arrayAdr, 0); + recN1->type = typeName; + if (!IsValidCodeAdr(arrayAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), typeName); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + return ""; + } + if (recN->SameName("@VarClr")) + { + DWORD strAdr = registers[16].value; //eax + if (IsValidImageAdr(strAdr)) + { + _ap = Adr2Pos(strAdr); + if (_ap >= 0) + { + recN1 = GetInfoRec(strAdr); + if (!recN1) recN1 = new InfoRec(_ap, ikVariant); + MakeGvar(recN1, strAdr, 0); + recN1->type = "Variant"; + if (!IsValidCodeAdr(strAdr)) recN1->AddXref('C', callAdr, callPos); + } + else + { + recN1 = AddToBSSInfos(strAdr, MakeGvarName(strAdr), "Variant"); + if (recN1) recN1->AddXref('C', callAdr, callPos); + } + } + return ""; + } + //@AsClass + if (recN->SameName("@AsClass")) + { + return registers[18].type; + } + //@IsClass + if (recN->SameName("@IsClass")) + { + return ""; + } + //@GetTls + if (recN->SameName("@GetTls")) + { + return "#TLS"; + } + //@AfterConstruction + if (recN->SameName("@AfterConstruction")) return ""; + } + //try prototype + BYTE callKind = recN->procInfo->flags & 7; + if (recN->procInfo->args && !callKind) + { + registers[16].result = 0; + registers[17].result = 0; + registers[18].result = 0; + + for (n = 0; n < recN->procInfo->args->Count; n++) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + regIdx = -1; + if (argInfo->Ndx == 0) //eax + regIdx = 16; + else if (argInfo->Ndx == 1) //edx + regIdx = 18; + else if (argInfo->Ndx == 2) //ecx + regIdx = 17; + if (regIdx == -1) continue; + if (argInfo->TypeDef == "") + { + if (registers[regIdx].type != "") + argInfo->TypeDef = TrimTypeName(registers[regIdx].type); + } + else + { + if (registers[regIdx].type == "") + { + registers[regIdx].type = argInfo->TypeDef; + //registers[regIdx].result = 1; + } + else + { + typeName = GetCommonType(argInfo->TypeDef, TrimTypeName(registers[regIdx].type)); + if (typeName != "") argInfo->TypeDef = typeName; + } + //Aliases ??????????? + } + + typeDef = argInfo->TypeDef; + //Local var (lea - remove ^ before type) + if (registers[regIdx].source == 'L') + { + if (SameText(typeDef, "Pointer")) + registers[regIdx].type = "Byte"; + else if (SameText(typeDef, "PAnsiChar") || SameText(typeDef, "PChar")) + registers[regIdx].type = typeDef.SubString(2, typeDef.Length() - 1); + else if (DelphiVersion >= 2009 && SameText(typeDef, "AnsiString")) + registers[regIdx].type = "UnicodeString"; + + registers[regIdx].result = 1; + continue; + } + //Local var + if (registers[regIdx].source == 'l') + { + continue; + } + //Arg + if ((registers[regIdx].source & 0xDF) == 'A') + { + continue; + } + itemAdr = registers[regIdx].value; + if (IsValidImageAdr(itemAdr)) + { + itemPos = Adr2Pos(itemAdr); + if (itemPos >= 0) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1 || recN1->kind != ikVMT) + { + registers[regIdx].result = 1; + + if (SameText(typeDef, "PShortString") || SameText(typeDef, "ShortString")) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + //var - use pointer + if (argInfo->Tag == 0x22) + { + strAdr = *((DWORD*)(Code + itemPos)); + if (IsValidCodeAdr(strAdr)) + { + _ap = Adr2Pos(strAdr); + len = *(Code + _ap); + SetFlags(cfData, _ap, len + 1); + } + else + { + SetFlags(cfData, itemPos, 4); + MakeGvar(recN1, itemAdr, 0); + if (typeDef != "") recN1->type = typeDef; + } + } + //val + else if (argInfo->Tag == 0x21) + { + recN1->kind = ikString; + len = *(Code + itemPos); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + recN1->SetName(TransformString(Code + itemPos + 1, len)); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + SetFlags(cfData, itemPos, len + 1); + } + } + else if (SameText(typeDef, "PAnsiChar") || SameText(typeDef, "PChar")) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + //var - use pointer + if (argInfo->Tag == 0x22) + { + strAdr = *((DWORD*)(Code + itemPos)); + if (IsValidCodeAdr(strAdr)) + { + _ap = Adr2Pos(strAdr); + len = strlen(Code + _ap); + SetFlags(cfData, _ap, len + 1); + } + else + { + SetFlags(cfData, itemPos, 4); + MakeGvar(recN1, itemAdr, 0); + if (typeDef != "") recN1->type = typeDef; + } + } + //val + else if (argInfo->Tag == 0x21) + { + recN1->kind = ikCString; + len = strlen(Code + itemPos); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + recN1->SetName(TransformString(Code + itemPos, len)); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + SetFlags(cfData, itemPos, len + 1); + } + } + else if (SameText(typeDef, "AnsiString") || + SameText(typeDef, "String") || + SameText(typeDef, "UString") || + SameText(typeDef, "UnicodeString")) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + //var - use pointer + if (argInfo->Tag == 0x22) + { + strAdr = *((DWORD*)(Code + itemPos)); + _ap = Adr2Pos(strAdr); + if (IsValidCodeAdr(strAdr)) + { + refcnt = *((int*)(Code + _ap - 8)); + len = *((int*)(Code + _ap - 4)); + if (refcnt == -1 && len >= 0 && len < 25000) + { + if (DelphiVersion < 2009) + { + SetFlags(cfData, _ap - 8, (8 + len + 1 + 3) & (-4)); + } + else + { + codePage = *((WORD*)(Code + _ap - 12)); + elemSize = *((WORD*)(Code + _ap - 10)); + SetFlags(cfData, _ap - 12, (12 + (len + 1)*elemSize + 3) & (-4)); + } + } + else + { + SetFlags(cfData, _ap, 4); + } + } + else + { + if (_ap >= 0) + { + SetFlags(cfData, itemPos, 4); + MakeGvar(recN1, itemAdr, 0); + if (typeDef != "") recN1->type = typeDef; + } + else if (_ap == -1) + { + recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); + } + } + } + //val + else if (argInfo->Tag == 0x21) + { + refcnt = *((int*)(Code + itemPos - 8)); + len = wcslen((wchar_t*)(Code + itemPos)); + if (DelphiVersion < 2009) + { + recN1->kind = ikLString; + } + else + { + codePage = *((WORD*)(Code + itemPos - 12)); + elemSize = *((WORD*)(Code + itemPos - 10)); + recN1->kind = ikUString; + } + if (refcnt == -1 && len >= 0 && len < 25000) + { + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + if (DelphiVersion < 2009) + recN1->SetName(TransformString(Code + itemPos, len)); + else + recN1->SetName(TransformUString(codePage, (wchar_t*)(Code + itemPos), len)); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + if (DelphiVersion < 2009) + SetFlags(cfData, itemPos - 8, (8 + len + 1 + 3) & (-4)); + else + SetFlags(cfData, itemPos - 12, (12 + (len + 1)*elemSize + 3) & (-4)); + } + else + { + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + recN1->SetName(""); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + SetFlags(cfData, itemPos, 4); + } + } + } + else if (SameText(typeDef, "WideString")) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + //var - use pointer + if (argInfo->Tag == 0x22) + { + strAdr = *((DWORD*)(Code + itemPos)); + _ap = Adr2Pos(strAdr); + if (IsValidCodeAdr(strAdr)) + { + len = *((int*)(Code + _ap - 4)); + SetFlags(cfData, _ap - 4, (4 + len + 1 + 3) & (-4)); + } + else + { + if (_ap >= 0) + { + SetFlags(cfData, itemPos, 4); + MakeGvar(recN1, itemAdr, 0); + if (typeDef != "") recN1->type = typeDef; + } + else if (_ap == -1) + { + recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); + } + } + } + //val + else if (argInfo->Tag == 0x21) + { + recN1->kind = ikWString; + len = wcslen((wchar_t*)(Code + itemPos)); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + WideString wStr = WideString((wchar_t*)(Code + itemPos)); + int size = WideCharToMultiByte(CP_ACP, 0, wStr, len, 0, 0, 0, 0); + if (size) + { + tmpBuf = new BYTE[size + 1]; + WideCharToMultiByte(CP_ACP, 0, wStr, len, (LPSTR)tmpBuf, size, 0, 0); + recN1->SetName(TransformString(tmpBuf, size)); //???size - 1 + delete[] tmpBuf; + } + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + SetFlags(cfData, itemPos - 4, (4 + len + 1 + 3) & (-4)); + } + } + else if (SameText(typeDef, "TGUID")) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikGUID); + recN1->kind = ikGUID; + SetFlags(cfData, itemPos, 16); + if (!recN1->HasName()) + { + if (IsValidCodeAdr(itemAdr)) + { + recN1->SetName(Guid2String(Code + itemPos)); + } + else + { + recN1->SetName(MakeGvarName(itemAdr)); + if (typeDef != "") recN1->type = typeDef; + } + } + } + else if (SameText(typeDef, "PResStringRec")) + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) + { + recN1 = new InfoRec(itemPos, ikResString); + recN1->type = "TResStringRec"; + recN1->ConcatName("SResString" + String(LastResStrNo)); + LastResStrNo++; + //Set Flags + SetFlags(cfData, itemPos, 8); + //Get Context + HINSTANCE hInst = LoadLibraryEx(SourceFile.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); + if (hInst) + { + DWORD resid = *((DWORD*)(Code + itemPos + 4)); + if (resid < 0x10000) + { + int Bytes = LoadString(hInst, (UINT)resid, buf, 1024); + recN1->rsInfo->value = String(buf, Bytes); + } + FreeLibrary(hInst); + } + } + } + else + { + recN1 = GetInfoRec(itemAdr); + if (!recN1) recN1 = new InfoRec(itemPos, ikData); + if (!recN1->HasName() && + recN1->kind != ikProc && + recN1->kind != ikFunc && + recN1->kind != ikConstructor && + recN1->kind != ikDestructor && + recN1->kind != ikRefine) + { + if (typeDef != "") recN1->type = typeDef; + } + } + } + } + else + { + _kind = GetTypeKind(typeDef, &_size); + if (_kind == ikInteger || + _kind == ikChar || + _kind == ikEnumeration || + _kind == ikFloat || + _kind == ikSet || + _kind == ikWChar) + { + _idx = BSSInfos->IndexOf(Val2Str8(itemAdr)); + if (_idx != -1) + { + recN1 = (PInfoRec)BSSInfos->Objects[_idx]; + delete recN1; + BSSInfos->Delete(_idx); + } + } + else + { + recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); + } + } + } + } + } + if (recN->kind == ikFunc) + { + return recN->type; + } + return ""; +} +//--------------------------------------------------------------------------- diff --git a/AnalyzeArguments.cpp b/AnalyzeArguments.cpp new file mode 100644 index 0000000..d078260 --- /dev/null +++ b/AnalyzeArguments.cpp @@ -0,0 +1,1207 @@ +//--------------------------------------------------------------------------- +String __fastcall TFMain_11011981::AnalyzeArguments(DWORD fromAdr) +{ + BYTE op; + bool kb; + bool bpBased; + bool emb, lastemb; + bool argA, argD, argC; + bool inA, inD, inC; + bool spRestored = false; + WORD bpBase, retBytes; + int num, instrLen, instrLen1, instrLen2, _procSize; + int firstPopRegIdx = -1, popBytes = 0, procStackSize = 0; + int fromPos, curPos, Pos, reg1Idx, reg2Idx, sSize; + DWORD b, curAdr, Adr, Adr1; + DWORD lastAdr = 0, lastCallAdr = 0, lastMovAdr = 0, lastMovImm = 0; + PInfoRec recN, recN1; + PARGINFO argInfo; + DWORD stack[256]; + int sp = -1; + int macroFrom, macroTo; + String minClassName, className = "", retType = ""; + DISINFO DisInfo, DisInfo1; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return ""; + if (IsFlagSet(cfEmbedded, fromPos)) return ""; + if (IsFlagSet(cfExport, fromPos)) return ""; + + recN = GetInfoRec(fromAdr); + if (!recN || !recN->procInfo) return ""; + + //If cfPass is set exit + if (IsFlagSet(cfPass, fromPos)) return recN->type; + + //Proc start + SetFlag(cfProcStart | cfPass, fromPos); + + //Skip Imports + if (IsFlagSet(cfImport, fromPos)) return recN->type; + + kb = (recN->procInfo->flags & PF_KBPROTO); + bpBased = (recN->procInfo->flags & PF_BPBASED); + emb = (recN->procInfo->flags & PF_EMBED); + bpBase = recN->procInfo->bpBase; + retBytes = recN->procInfo->retBytes; + + //If constructor or destructor get class name + if (recN->kind == ikConstructor || recN->kind == ikDestructor) + className = ExtractClassName(recN->GetName()); + //If ClassName not given and proc is dynamic, try to find minimal class + if (className == "" && (recN->procInfo->flags & PF_DYNAMIC) && recN->xrefs) + { + minClassName = ""; + for (int n = 0; n < recN->xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; + if (recX->type == 'D') + { + className = GetClsName(recX->adr); + if (minClassName == "" || !IsInheritsByClassName(className, minClassName)) minClassName = className; + } + } + if (minClassName != "") className = minClassName; + } + //If ClassName not given and proc is virtual, try to find minimal class + if (className == "" && (recN->procInfo->flags & PF_VIRTUAL) && recN->xrefs) + { + minClassName = ""; + for (int n = 0; n < recN->xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; + if (recX->type == 'D') + { + className = GetClsName(recX->adr); + if (minClassName == "" || !IsInheritsByClassName(className, minClassName)) minClassName = className; + } + } + if (minClassName != "") className = minClassName; + } + + argA = argD = argC = true; //On entry + inA = inD = inC = false; //No arguments + + _procSize = GetProcSize(fromAdr); + curPos = fromPos; curAdr = fromAdr; + + while (1) + { + if (curAdr >= CodeBase + TotalSize) break; + //Skip exception table + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + curPos += 4 + 8*num; curAdr += 4 + 8*num; + continue; + } + + BYTE b1 = Code[curPos]; + BYTE b2 = Code[curPos + 1]; + if (!b1 && !b2 && !lastAdr) break; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) break; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + + op = Disasm.GetOp(DisInfo.Mnem); + //Code + SetFlags(cfCode, curPos, instrLen); + //Instruction begin + SetFlag(cfInstruction, curPos); + + if (curAdr >= lastAdr) lastAdr = 0; + + if (op == OP_JMP) + { + if (curAdr == fromAdr) break; + if (DisInfo.OpType[0] == otMEM) + { + if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) break; + } + if (DisInfo.OpType[0] == otIMM) + { + Adr = DisInfo.Immediate; + if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) break; + if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) break; + if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) break; + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + if (DisInfo.Ret) + { + //End of proc + if (!lastAdr || curAdr == lastAdr) + { + //Get last instruction + curPos -= instrLen; + if ((DisInfo.Ret && !IsFlagSet(cfSkip, curPos)) || //ret not in SEH + IsFlagSet(cfCall, curPos)) //@Halt0 + { + if (IsFlagSet(cfCall, curPos)) spRestored = true; //acts like mov esp, ebp + + sp = -1; + SetFlags(cfFrame, curPos, instrLen); + //ret - stop analyze output regs + lastCallAdr = 0; firstPopRegIdx = -1; popBytes = 0; + //define all pop registers (ret skipped) + for (Pos = curPos - 1; Pos >= fromPos; Pos--) + { + b = Flags[Pos]; + if (b & cfInstruction) + { + //pop instruction + if (b & cfPop) + { + //pop ecx + if (b & cfSkip) break; + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); + firstPopRegIdx = DisInfo1.OpRegIdx[0]; + popBytes += 4; + SetFlags(cfFrame, Pos, instrLen1); + } + else + { + //skip frame instruction + if (b & cfFrame) continue; + //set eax - function + if (b & cfSetA) + { + recN1 = GetInfoRec(fromAdr); + recN1->procInfo->flags |= PF_OUTEAX; + if (!kb && !(recN1->procInfo->flags & (PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->kind = ikFunc; + Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); + op = Disasm.GetOp(DisInfo1.Mnem); + //if setXX - return type is Boolean + if (op == OP_SET) recN1->type = "Boolean"; + } + } + break; + } + } + } + } + if (firstPopRegIdx!= -1) + { + //Skip pushed regs + if (spRestored) + { + for (Pos = fromPos;;Pos++) + { + b = Flags[Pos]; + //Proc end + //if (Pos != fromPos && (b & cfProcEnd)) + if (_procSize && Pos - fromPos + 1 >= _procSize) break; + if (b & cfInstruction) + { + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); + SetFlags(cfFrame, Pos, instrLen1); + if ((b & cfPush) && (DisInfo1.OpRegIdx[0] == firstPopRegIdx)) break; + } + } + } + else + { + for (Pos = fromPos;;Pos++) + { + if (!popBytes) break; + + b = Flags[Pos]; + //End of proc + //if (Pos != fromPos && (b & cfProcEnd)) + if (_procSize && Pos - fromPos + 1 >= _procSize) break; + if (b & cfInstruction) + { + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); + op = Disasm.GetOp(DisInfo1.Mnem); + SetFlags(cfFrame, Pos, instrLen1); + //add esp,... + if (op == OP_ADD && DisInfo1.OpRegIdx[0] == 20) + { + popBytes += (int)DisInfo1.Immediate; + continue; + } + //sub esp,... + if (op == OP_SUB && DisInfo1.OpRegIdx[0] == 20) + { + popBytes -= (int)DisInfo1.Immediate; + continue; + } + if (b & cfPush) popBytes -= 4; + } + } + } + } + //If no prototype, try add information from analyze arguments result + if (!recN->HasName() && className != "") + { + //dynamic + if (recN->procInfo->flags & PF_DYNAMIC) + { + } + else + { + } + } + if (!kb) + { + if (inA) + { + if (className != "") + recN->procInfo->AddArg(0x21, 0, 4, "Self", className); + else + recN->procInfo->AddArg(0x21, 0, 4, "", ""); + } + if (inD) + { + if (recN->kind == ikConstructor || recN->kind == ikDestructor) + recN->procInfo->AddArg(0x21, 1, 4, "_Dv__", "Boolean"); + else + recN->procInfo->AddArg(0x21, 1, 4, "", ""); + } + if (inC) + { + recN->procInfo->AddArg(0x21, 2, 4, "", ""); + } + } + break; + } + if (!IsFlagSet(cfSkip, curPos)) sp = -1; + } + + if (op == OP_MOV) + { + lastMovAdr = DisInfo.Offset; + lastMovImm = DisInfo.Immediate; + } + //init stack via loop + if (IsFlagSet(cfLoc, curPos)) + { + recN1 = GetInfoRec(curAdr); + if (recN1 && recN1->xrefs && recN1->xrefs->Count == 1) + { + PXrefRec recX = (PXrefRec)recN1->xrefs->Items[0]; + Adr = recX->adr + recX->offset; + if (Adr > curAdr) + { + sSize = IsInitStackViaLoop(curAdr, Adr); + if (sSize) + { + procStackSize += sSize * lastMovImm; + //skip jne + instrLen = Disasm.Disassemble(Code + Adr2Pos(Adr), (__int64)Adr, 0, 0); + curAdr = Adr + instrLen; curPos = Adr2Pos(curAdr); + SetFlags(cfFrame, fromPos, curAdr - fromAdr); + continue; + } + } + } + } + //add (sub) esp,... + if (DisInfo.OpRegIdx[0] == 20 && DisInfo.OpType[1] == otIMM) + { + if (op == OP_ADD) + { + if ((int)DisInfo.Immediate < 0) procStackSize -= (int)DisInfo.Immediate; + } + if (op == OP_SUB) + { + if ((int)DisInfo.Immediate > 0) procStackSize += (int)DisInfo.Immediate; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + /* + //dec reg + if (op == OP_DEC && DisInfo.Op1Type == otREG) + { + //Save (dec reg) address + Adr = curAdr; + //Look next instruction + curPos += instrLen; + curAdr += instrLen; + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo1, 0); + //If jne @1, where @1 < adr of jne, when make frame from begin if Stack inited via loop + if (DisInfo1.Conditional && DisInfo1.Immediate < curAdr && DisInfo1.Immediate >= fromAdr) + { + if (IsInitStackViaLoop(DisInfo1.Immediate, Adr)) + SetFlags(cfFrame, fromPos, curPos + instrLen - fromPos + 1); + } + continue; + } + */ + + //mov esp, ebp + if (b1 == 0x8B && b2 == 0xE5) spRestored = true; + + if (!IsFlagSet(cfSkip, curPos)) + { + if (IsFlagSet(cfPush, curPos)) + { + if (curPos != fromPos && sp < 255) + { + sp++; + stack[sp] = curPos; + } + } + if (IsFlagSet(cfPop, curPos) && sp >= 0) + { + macroFrom = stack[sp]; + SetFlag(cfBracket, macroFrom); + macroTo = curPos; + SetFlag(cfBracket, macroTo); + sp--; + } + } + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + if (!IsValidCodeAdr(DisInfo.Offset)) break; + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Taqble address - last 4 bytes of instruction + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Analyze gap to find table cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //If cTblAdr exists, skip it + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + Pos += CNum; Adr += CNum; + } + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } +//---------------------------------- +//PosTry: xor reg, reg +// push ebp +// push offset @1 +// push fs:[reg] +// mov fs:[reg], esp +// ... +//@2: ... +//At @1 we have various situations: +//---------------------------------- +//@1: jmp @HandleFinally +// jmp @2 +//---------------------------------- +//@1: jmp @HandleAnyException +// call DoneExcept +//---------------------------------- +//@1: jmp HandleOnException +// dd num +//Follow the table of num records like: +// dd offset ExceptionInfo +// dd offset ExceptionProc +//---------------------------------- + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0 && Pos - NPos < MAX_DISASSEMBLE) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN1 = GetInfoRec(DisInfo.Immediate); + if (recN1) + { + if (recN1->SameName("@HandleFinally")) + { + //ret + jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN1->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Pos += 4; + //dd offset ExceptionProc + Pos += 4; + } + } + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + } + while (1) + { + //Call - stop analyze of arguments + if (DisInfo.Call) + { + lastemb = false; + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + recN1 = GetInfoRec(Adr); + if (recN1 && recN1->procInfo) + { + lastemb = (recN1->procInfo->flags & PF_EMBED); + WORD retb; + //@XStrCatN + if (recN1->SameName("@LStrCatN") || + recN1->SameName("@WStrCatN") || + recN1->SameName("@UStrCatN") || + recN1->SameName("Format")) + { + retb = 0; + } + else + retb = recN1->procInfo->retBytes; + + if (retb && sp >= retb) + sp -= retb; + else + sp = -1; + } + else + sp = -1; + //call not always preserve registers eax, edx, ecx + if (recN1) + { + //@IntOver, @BoundErr nothing change + if (!recN1->SameName("@IntOver") && + !recN1->SameName("@BoundErr")) + { + argA = argD = argC = false; + } + } + else + { + argA = argD = argC = false; + } + } + else + { + argA = argD = argC = false; + sp = -1; + } + break; + } + //jmp - stop analyze of output arguments + if (op == OP_JMP) + { + lastCallAdr = 0; + break; + } + //cop ..., [ebp + Offset] + if (!kb && bpBased && DisInfo.BaseReg == 21 && DisInfo.IndxReg == -1 && (int)DisInfo.Offset > 0) + { + recN1 = GetInfoRec(fromAdr); + //For embedded procs we have on1 additional argument (pushed on stack first), that poped from stack by instrcution pop ecx + if (!emb || (int)DisInfo.Offset != retBytes + bpBase) + { + int argSize = DisInfo.OpSize; + String argType = ""; + if (argSize == 10) argType = "Extended"; + //Each argument in stack has size 4*N bytes + if (argSize < 4) argSize = 4; + argSize = ((argSize + 3) / 4) * 4; + recN1->procInfo->AddArg(0x21, (int)DisInfo.Offset, argSize, "", argType); + } + } + //Instruction pop reg always change reg + if (op == OP_POP && DisInfo.OpType[0] == otREG) + { + //eax + if (DisInfo.OpRegIdx[0] == 16) + { + //Forget last call and set flag cfSkip, if it was call of embedded proc + if (lastCallAdr) + { + if (lastemb) + { + SetFlag(cfSkip, curPos); + lastemb = false; + } + lastCallAdr = 0; + } + + if (argA && !inA) + { + argA = false; + if (!inD) argD = false; + if (!inC) argC = false; + } + } + //edx + if (DisInfo.OpRegIdx[0] == 18) + { + if (argD && !inD) + { + argD = false; + if (!inC) argC = false; + } + } + //ecx + if (DisInfo.OpRegIdx[0] == 17) + { + if (argC && !inC) argC = false; + } + break; + } + //cdq always change edx; eax may be output argument of last call + if (op == OP_CDQ) + { + if (lastCallAdr) + { + recN1 = GetInfoRec(lastCallAdr); + if (recN1 && recN1->procInfo && + !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->procInfo->flags |= PF_OUTEAX; + recN1->kind = ikFunc; + } + lastCallAdr = 0; + } + if (argD && !inD) + { + argD = false; + if (!inC) argC = false; + } + break; + } + if (DisInfo.Float) + { + //fstsw, fnstsw always change eax + if (!memcmp(DisInfo.Mnem + 1, "stsw", 4) || !memcmp(DisInfo.Mnem + 1, "nstsw", 5)) + { + if (DisInfo.OpType[0] == otREG && (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0)) + { + if (lastCallAdr) lastCallAdr = 0; + + if (argA && !inA) + { + argA = false; + if (!inD) argD = false; + if (!inC) argC = false; + } + } + SetFlags(cfSkip, curPos, instrLen); + break; + } + //Instructions fst, fstp after call means that it was call of function + if (!memcmp(DisInfo.Mnem + 1, "st", 2)) + { + Pos = GetNearestUpInstruction(curPos, fromPos, 1); + if (Pos != -1 && IsFlagSet(cfCall, Pos)) + { + if (lastCallAdr) + { + recN1 = GetInfoRec(lastCallAdr); + if (recN1 && recN1->procInfo && + !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->procInfo->flags |= PF_OUTEAX; + recN1->kind = ikFunc; + } + lastCallAdr = 0; + } + } + break; + } + } + //mul, div ????????????????????????????????????????????????????????????????????? + //xor reg, reg always change register + if (op == OP_XOR && DisInfo.OpType[0] == DisInfo.OpType[1] && DisInfo.OpRegIdx[0] == DisInfo.OpRegIdx[1]) + { + if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) + { + if (lastCallAdr) lastCallAdr = 0; + } + if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) + { + if (lastCallAdr) lastCallAdr = 0; + } + + //eax, ax, ah, al + if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) + { + SetFlag(cfSetA, curPos); + if (argA && !inA) + { + argA = false; + if (!inD) argD = false; + if (!inC) argC = false; + } + } + //edx, dx, dh, dl + if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) + { + SetFlag(cfSetD, curPos); + if (argD && !inD) + { + argD = false; + if (!inC) argC = false; + } + } + //ecx, cx, ch, cl + if (DisInfo.OpRegIdx[0] == 17 || DisInfo.OpRegIdx[0] == 9 || DisInfo.OpRegIdx[0] == 5 || DisInfo.OpRegIdx[0] == 1) + { + SetFlag(cfSetC, curPos); + if (argC && !inC) argC = false; + } + break; + } + //If eax, edx, ecx in memory address - always used as registers + if (DisInfo.BaseReg != -1 || DisInfo.IndxReg != -1) + { + if (DisInfo.BaseReg == 16 || DisInfo.IndxReg == 16) + { + if (lastCallAdr) + { + recN1 = GetInfoRec(lastCallAdr); + if (recN1 && recN1->procInfo && + !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->procInfo->flags |= PF_OUTEAX; + recN1->kind = ikFunc; + } + lastCallAdr = 0; + } + } + if (DisInfo.BaseReg == 16 || DisInfo.IndxReg == 16) + { + if (argA && !inA) + { + inA = true; + argA = false; + } + } + if (DisInfo.BaseReg == 18 || DisInfo.IndxReg == 18) + { + if (argD && !inD) + { + inD = true; + argD = false; + if (!inA) + { + inA = true; + argA = false; + } + } + } + if (DisInfo.BaseReg == 17 || DisInfo.IndxReg == 17) + { + if (argC && !inC) + { + inC = true; + argC = false; + if (!inA) + { + inA = true; + argA = false; + } + if (!inD) + { + inD = true; + argD = false; + } + } + } + } + //xchg + if (op == OP_XCHG) + { + if (DisInfo.OpType[0] == otREG) + { + if (DisInfo.OpRegIdx[0] == 16) //eax + { + if (lastCallAdr) + { + recN1 = GetInfoRec(lastCallAdr); + if (recN1 && recN1->procInfo && + !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->procInfo->flags |= PF_OUTEAX; + recN1->kind = ikFunc; + } + lastCallAdr = 0; + } + } + if (DisInfo.OpRegIdx[0] == 16) //eax + { + SetFlag(cfSetA, curPos); + if (argA && !inA) + { + inA = true; + argA = false; + } + } + if (DisInfo.OpRegIdx[0] == 18) //edx + { + SetFlag(cfSetD, curPos); + if (argD && !inD) + { + inD = true; + argD = false; + if (!inA) + { + inA = true; + argA = false; + } + } + } + if (DisInfo.OpRegIdx[0] == 17) //ecx + { + SetFlag(cfSetC, curPos); + //xchg ecx, [ebp...] - ecx used as argument + if (DisInfo.BaseReg == 21) + { + inC = true; + argC = false; + if (!inA) + { + inA = true; + argA = false; + } + if (!inD) + { + inD = true; + argD = false; + } + //Set cfFrame upto start of procedure + SetFlags(cfFrame, fromPos, (curPos + instrLen - fromPos)); + } + else if (argC && !inC) + { + inC = true; + argC = false; + if (!inA) + { + inA = true; + argA = false; + } + if (!inD) + { + inD = true; + argD = false; + } + } + } + } + if (DisInfo.OpType[1] == otREG) + { + if (DisInfo.OpRegIdx[1] == 16) + { + if (lastCallAdr) + { + recN1 = GetInfoRec(lastCallAdr); + if (recN1 && recN1->procInfo && + !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->procInfo->flags |= PF_OUTEAX; + recN1->kind = ikFunc; + } + lastCallAdr = 0; + } + } + if (DisInfo.OpRegIdx[1] == 16) + { + SetFlag(cfSetA, curPos); + if (argA && !inA) + { + inA = true; + argA = false; + } + } + if (DisInfo.OpRegIdx[1] == 18) + { + SetFlag(cfSetD, curPos); + if (argD && !inD) + { + inD = true; + argD = false; + if (!inA) + { + inA = true; + argA = false; + } + } + } + if (DisInfo.OpRegIdx[1] == 17) + { + SetFlag(cfSetC, curPos); + if (argC && !inC) + { + inC = true; + argC = false; + if (!inA) + { + inA = true; + argA = false; + } + if (!inD) + { + inD = true; + argD = false; + } + } + } + } + break; + } + //cop ..., reg + if (DisInfo.OpType[1] == otREG) + { + if (DisInfo.OpRegIdx[1] == 16 || DisInfo.OpRegIdx[1] == 8 || DisInfo.OpRegIdx[1] == 0) + { + if (lastCallAdr) + { + recN1 = GetInfoRec(lastCallAdr); + if (recN1 && recN1->procInfo && + !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && + recN1->kind != ikConstructor && recN1->kind != ikDestructor) + { + recN1->procInfo->flags |= PF_OUTEAX; + recN1->kind = ikFunc; + } + lastCallAdr = 0; + } + } + //eax, ax, ah, al + if (DisInfo.OpRegIdx[1] == 16 || DisInfo.OpRegIdx[1] == 8 || DisInfo.OpRegIdx[1] == 4 || DisInfo.OpRegIdx[1] == 0) + { + if (argA && !inA) + { + inA = true; + argA = false; + } + } + //edx, dx, dh, dl + if (DisInfo.OpRegIdx[1] == 18 || DisInfo.OpRegIdx[1] == 10 || DisInfo.OpRegIdx[1] == 6 || DisInfo.OpRegIdx[1] == 2) + { + if (argD && !inD) + { + inD = true; + argD = false; + if (!inA) + { + inA = true; + argA = false; + } + } + } + //ecx, cx, ch, cl + if (DisInfo.OpRegIdx[1] == 17 || DisInfo.OpRegIdx[1] == 9 || DisInfo.OpRegIdx[1] == 5 || DisInfo.OpRegIdx[1] == 1) + { + if (argC && !inC) + { + inC = true; + argC = false; + if (!inA) + { + inA = true; + argA = false; + } + if (!inD) + { + inD = true; + argD = false; + } + } + } + } + + if (DisInfo.OpType[0] == otREG && op != OP_UNK && op != OP_PUSH) + { + if (op != OP_MOV && op != OP_LEA && op != OP_SET) + { + //eax, ax, ah, al + if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) + { + if (argA && !inA) + { + inA = true; + argA = false; + } + } + //edx, dx, dh, dl + if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) + { + if (argD && !inD) + { + inD = true; + argD = false; + if (!inA) + { + inA = true; + argA = false; + } + } + } + //ecx, cx, ch, cl + if (DisInfo.OpRegIdx[0] == 17 || DisInfo.OpRegIdx[0] == 9 || DisInfo.OpRegIdx[0] == 5 || DisInfo.OpRegIdx[0] == 1) + { + if (argC && !inC) + { + inC = true; + argC = false; + if (!inA) + { + inA = true; + argA = false; + } + if (!inD) + { + inD = true; + argD = false; + } + } + } + } + else + { + //eax, ax, ah, al + if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) + { + SetFlag(cfSetA, curPos); + if (argA && !inA) + { + argA = false; + if (!inD) argD = false; + if (!inC) argC = false; + } + if (lastCallAdr) lastCallAdr = 0; + } + //edx, dx, dh, dl + if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) + { + SetFlag(cfSetD, curPos); + if (argD && !inD) + { + argD = false; + if (!inC) argC = false; + } + if (lastCallAdr) lastCallAdr = 0; + } + //ecx, cx, ch, cl + if (DisInfo.OpRegIdx[0] == 17 || DisInfo.OpRegIdx[0] == 9 || DisInfo.OpRegIdx[0] == 5 || DisInfo.OpRegIdx[0] == 1) + { + SetFlag(cfSetC, curPos); + if (argC && !inC) argC = false; + } + } + } + break; + } + + if (DisInfo.Call) //call sub_XXXXXXXX + { + lastCallAdr = 0; + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + retType = AnalyzeArguments(Adr); + lastCallAdr = Adr; + + recN1 = GetInfoRec(Adr); + if (recN1 && recN1->HasName()) + { + //Hide some procedures + //@Halt0 is not executed + if (recN1->SameName("@Halt0")) + { + SetFlags(cfSkip, curPos, instrLen); + if (fromAdr == EP && !lastAdr) break; + } + //Procs together previous unstruction + else if (recN1->SameName("@IntOver") || + recN1->SameName("@InitImports") || + recN1->SameName("@InitResStringImports")) + { + Pos = GetNearestUpInstruction(curPos, fromPos, 1); + if (Pos != -1) SetFlags(cfSkip, Pos, (curPos - Pos) + instrLen); + } + //@BoundErr + else if (recN1->SameName("@BoundErr")) + { + if (IsFlagSet(cfLoc, curPos)) + { + Pos = GetNearestUpInstruction(curPos, fromPos, 1); + Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); + if (DisInfo1.Branch) + { + Pos = GetNearestUpInstruction(Pos, fromPos, 3); + SetFlags(cfSkip, Pos, (curPos - Pos) + instrLen); + } + } + else + { + Pos = GetNearestUpInstruction(curPos, fromPos, 1); + Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); + if (DisInfo1.Branch) + { + Pos = GetNearestUpInstruction(Pos, fromPos, 1); + if (IsFlagSet(cfPop, Pos)) + { + Pos = GetNearestUpInstruction(Pos, fromPos, 3); + } + SetFlags(cfSkip, Pos, (curPos - Pos) + instrLen); + } + } + } + //Not in source code + else if (recN1->SameName("@_IOTest") || + recN1->SameName("@InitExe") || + recN1->SameName("@InitLib") || + recN1->SameName("@DoneExcept")) + { + SetFlags(cfSkip, curPos, instrLen); + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (b1 == 0xEB || //short relative abs jmp or cond jmp + (b1 >= 0x70 && b1 <= 0x7F) || + (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + if (b1 == 0xE9) //relative abs jmp or cond jmp + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + recN1 = GetInfoRec(Adr); + if (!recN1 && Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + curPos += instrLen; curAdr += instrLen; + } + //Check matching ret bytes and summary size of stack arguments + if (bpBased) + { + if (recN->procInfo->args) + { + int delta = retBytes; + for (int n = 0; n < recN->procInfo->args->Count; n++) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + if (argInfo->Ndx > 2) delta -= argInfo->Size; + } + if (delta < 0) + { + //If delta between N bytes (in "ret N" instruction) and total size of argumnets != 0 + recN->procInfo->flags |= PF_ARGSIZEG; + //delta = 4 and proc can be embbedded - allow that it really embedded + if (delta == 4 && (recN->procInfo->flags & PF_MAYBEEMBED)) + { + //Ñòàâèì ôëàæîê PF_EMBED + recN->procInfo->flags |= PF_EMBED; + //Skip following after call instrcution "pop ecx" + for (int n = 0; n < recN->xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; + if (recX->type == 'C') + { + Adr = recX->adr + recX->offset; Pos = Adr2Pos(Adr); + instrLen = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Pos += instrLen; + if (Code[Pos] == 0x59) SetFlag(cfSkip, Pos); + } + } + } + } + //If delta < 0, then part of arguments can be unusable + else if (delta < 0) + { + recN->procInfo->flags |= PF_ARGSIZEL; + } + } + } + recN = GetInfoRec(fromAdr); + //if PF_OUTEAX not set - Procedure + if (!kb && !(recN->procInfo->flags & PF_OUTEAX)) + { + if (recN->kind != ikConstructor && recN->kind != ikDestructor) + { + recN->kind = ikProc; + } + } + + recN->procInfo->stackSize = procStackSize + 0x1000; + if (lastCallAdr) return retType; + return ""; +} +//--------------------------------------------------------------------------- diff --git a/CXrefs.cpp b/CXrefs.cpp new file mode 100644 index 0000000..0d26e65 --- /dev/null +++ b/CXrefs.cpp @@ -0,0 +1,167 @@ +void __fastcall TFMain_11011981::ShowCodeXrefs(DWORD Adr, int selIdx) +{ + lbCXrefs->Clear(); + PInfoRec recN = GetInfoRec(Adr); + if (recN && recN->xrefs) + { + int wid, maxwid = 0; + TCanvas *canvas = lbCXrefs->Canvas; + DWORD pAdr = 0; + char f = 2; + + lbCXrefs->Items->BeginUpdate(); + + for (int m = 0; m < recN->xrefs->Count; m++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; + String line = " " + Val2Str8(recX->adr + recX->offset) + " " + recX->type; + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + PUnitRec recU = GetUnit(recX->adr); + if (recU && recU->kb) line[1] ^= 1; + if (pAdr != recX->adr) f ^= 2; line[1] ^= f; + pAdr = recX->adr; + lbCXrefs->Items->Add(line); + } + lbCXrefs->ScrollWidth = maxwid + 2; + lbCXrefs->ItemIndex = selIdx; + lbCXrefs->ItemHeight = lbCXrefs->Canvas->TextHeight("T"); + lbCXrefs->Items->EndUpdate(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbXrefsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + TListBox *lb = (TListBox*)Sender; + if (lb->CanFocus()) ActiveControl = lb; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbXrefsDblClick(TObject *Sender) +{ + char type[2]; + DWORD adr; + PROCHISTORYREC rec; + + TListBox *lb = (TListBox*)Sender; + if (lb->ItemIndex < 0) return; + + String item = lb->Items->Strings[lb->ItemIndex]; + sscanf(item.c_str() + 1, "%lX%2c", &adr, type); + + if (type[1] == 'D') + { + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->kind == ikVMT) + { + ShowClassViewer(adr); + WhereSearch = SEARCH_CLASSVIEWER; + + if (!rgViewerMode->ItemIndex) + { + TreeSearchFrom = tvClassesFull->Items->Item[0]; + } + else + { + BranchSearchFrom = tvClassesShort->Items->Item[0]; + } + //Ñíà÷àëà èùåì êëàññ + String text = "#" + Val2Str8(adr); + FindText(text); + //Ïîòîì - òåêóùóþ ïðîöåäóðó + if (!rgViewerMode->ItemIndex) + { + if (tvClassesFull->Selected) + TreeSearchFrom = tvClassesFull->Selected; + else + TreeSearchFrom = tvClassesFull->Items->Item[0]; + } + else + { + if (tvClassesShort->Selected) + BranchSearchFrom = tvClassesShort->Selected; + else + BranchSearchFrom = tvClassesShort->Items->Item[0]; + } + text = "#" + Val2Str8(CurProcAdr); + FindText(text); + return; + } + } + + for (int m = Adr2Pos(adr); m >= 0; m--) + { + if (IsFlagSet(cfProcStart, m)) + { + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(Pos2Adr(m), adr, -1, -1); + CodeHistoryPush(&rec); + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbXrefsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + if (Key == VK_RETURN) lbXrefsDblClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbXrefsDrawItem(TWinControl *Control, + int Index, TRect &Rect, TOwnerDrawState State) +{ + int flags; + TColor _color; + TListBox *lb; + TCanvas *canvas; + String text, str; + + lb = (TListBox*)Control; + canvas = lb->Canvas; + SaveCanvas(canvas); + + if (Index < lb->Count) + { + flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); + if (!Control->UseRightToLeftAlignment()) + Rect.Left += 2; + else + Rect.Right -= 2; + + text = lb->Items->Strings[Index]; + //lb->ItemHeight = canvas->TextHeight(text); + str = text.SubString(2, text.Length() - 1); + + if (text[1] & 2) + { + if (!State.Contains(odSelected)) + canvas->Brush->Color = TColor(0xE7E7E7); + else + canvas->Brush->Color = TColor(0xFF0000); + } + canvas->FillRect(Rect); + + //Xrefs to Kb units + if (text[1] & 1) + { + if (!State.Contains(odSelected)) + _color = TColor(0xC08000); //Blue + else + _color = TColor(0xBBBBBB); //LightGray + } + //Others + else + { + if (!State.Contains(odSelected)) + _color = TColor(0x00B000); //Green + else + _color = TColor(0xBBBBBB); //LightGray + } + Rect.Right = Rect.Left; + DrawOneItem(str, canvas, Rect, _color, flags); + } + RestoreCanvas(canvas); +} +//--------------------------------------------------------------------------- diff --git a/Decompiler.cpp b/Decompiler.cpp new file mode 100644 index 0000000..afd15d5 --- /dev/null +++ b/Decompiler.cpp @@ -0,0 +1,10681 @@ +//--------------------------------------------------------------------------- +#include +#include +#pragma hdrstop + +#include +#include "Decompiler.h" +#include "Main.h" +#include "Misc.h" +#include "TypeInfo.h" +#include "InputDlg.h" +//--------------------------------------------------------------------------- +extern int DelphiVersion; +extern MDisasm Disasm; +extern DWORD CodeBase; +extern DWORD CurProcAdr; +extern DWORD EP; +extern DWORD ImageBase; +extern BYTE *Image; +extern BYTE *Code; +extern PInfoRec *Infos; +extern TStringList *BSSInfos; +extern DWORD *Flags; +extern int cVmtSelfPtr; +extern char StringBuf[MAXSTRBUFFER]; +extern MKnowledgeBase KnowledgeBase; +//--------------------------------------------------------------------------- +String __fastcall GetString(PITEM item, BYTE precedence) +{ + String _val = item->Value; + + if (_val == "") + { + if (item->Flags & IF_INTVAL) + return GetImmString(item->Type, item->IntValue); + if (item->Name != "") + _val = item->Name; + } + if (item->Precedence && item->Precedence < precedence) return "(" + _val + ")"; + return _val; +} +//--------------------------------------------------------------------------- +String __fastcall GetFieldName(PFIELDINFO fInfo) +{ + if (fInfo->Name == "") return String("?f") + Val2Str0(fInfo->Offset); + return fInfo->Name; +} +//--------------------------------------------------------------------------- +String __fastcall GetArgName(PARGINFO argInfo) +{ + if (argInfo->Name == "") return String("arg_") + Val2Str0(argInfo->Ndx); + return argInfo->Name; +} +//--------------------------------------------------------------------------- +String __fastcall GetGvarName(DWORD adr) +{ + if (!IsValidImageAdr(adr)) return "?"; + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->HasName()) return recN->GetName(); + return MakeGvarName(adr); +} +//--------------------------------------------------------------------------- +//'A'-JO;'B'-JNO;'C'-JB;'D'-JNB;'E'-JZ;'F'-JNZ;'G'-JBE;'H'-JA; +//'I'-JS;'J'-JNS;'K'-JP;'L'-JNP;'M'-JL;'N'-JGE;'O'-JLE;'P'-JG +//'Q'-in;'R'-not in;'S'-is +String DirectConditions[19] = {"", "", "<", ">=", "=", "<>", "<=", ">", "", "", "", "", "<", ">=", "<=", ">", "not in", "in", "is"}; +String __fastcall GetDirectCondition(char c) +{ + if (c >= 'A') + return DirectConditions[c - 'A']; + else + return "?"; +} +//--------------------------------------------------------------------------- +String InvertConditions[19] = {"", "", ">=", "<", "<>", "=", ">", "<=", "", "", "", "", ">=", "<", ">", "<=", "in", "not in", "is not"}; +String __fastcall GetInvertCondition(char c) +{ + if (c >= 'A') + return InvertConditions[c - 'A']; + else + return "?"; +} +//--------------------------------------------------------------------------- +void __fastcall InitItem(PITEM Item) +{ + Item->Flags = 0; + Item->Precedence = PRECEDENCE_ATOM; + Item->Size = 0; + Item->Offset = 0; + Item->IntValue = 0; + Item->Value = ""; + Item->Value1 = ""; + Item->Type = ""; + Item->Name = ""; +} +//--------------------------------------------------------------------------- +void __fastcall AssignItem(PITEM DstItem, PITEM SrcItem) +{ + DstItem->Flags = SrcItem->Flags; + DstItem->Precedence = SrcItem->Precedence; + DstItem->Size = SrcItem->Size; + DstItem->IntValue = SrcItem->IntValue; + DstItem->Value = SrcItem->Value; + DstItem->Value1 = SrcItem->Value1; + DstItem->Type = SrcItem->Type; + DstItem->Name = SrcItem->Name; +} +//--------------------------------------------------------------------------- +__fastcall TNamer::TNamer() +{ + MaxIdx = -1; + Names = new TStringList; + Names->Sorted = true; +} +//--------------------------------------------------------------------------- +__fastcall TNamer::~TNamer() +{ + delete Names; +} +//--------------------------------------------------------------------------- +String __fastcall TNamer::MakeName(String shablon) +{ + char name[1024]; + + if (shablon[1] == 'T') + { + int idx = -1; + int len = sprintf(name, "_%s_", shablon.c_str() + 1); + for (int n = 0; n <= MaxIdx; n++) + { + sprintf(name + len, "%d", n); + if (Names->IndexOf(String(name)) != -1) idx = n; + } + if (idx == -1) + { + Names->Add(String(name)); + if (MaxIdx == -1) MaxIdx = 0; + } + else + { + sprintf(name + len, "%d", idx + 1); + Names->Add(String(name)); + if (idx + 1 > MaxIdx) MaxIdx = idx + 1; + } + } + return String(name); +} +//--------------------------------------------------------------------------- +__fastcall TForInfo::TForInfo(bool ANoVar, bool ADown, int AStopAdr, String AFrom, String ATo, BYTE AVarType, int AVarIdx, BYTE ACntType, int ACntIdx) +{ + NoVar = ANoVar; + Down = ADown; + StopAdr = AStopAdr; + From = AFrom; + To = ATo; + VarInfo.IdxType = AVarType; + VarInfo.IdxValue = AVarIdx; + CntInfo.IdxType = ACntType; + CntInfo.IdxValue = ACntIdx; +} +//--------------------------------------------------------------------------- +__fastcall TWhileInfo::TWhileInfo(bool ANoCond) +{ + NoCondition = ANoCond; +} +//--------------------------------------------------------------------------- +__fastcall TLoopInfo::TLoopInfo(BYTE AKind, DWORD AContAdr, DWORD ABreakAdr, DWORD ALastAdr) +{ + Kind = AKind; + ContAdr = AContAdr; + BreakAdr = ABreakAdr; + LastAdr = ALastAdr; + forInfo = 0; + whileInfo = 0; +} +//--------------------------------------------------------------------------- +__fastcall TLoopInfo::~TLoopInfo() +{ +} +//--------------------------------------------------------------------------- +__fastcall TDecompileEnv::TDecompileEnv(DWORD AStartAdr, int ASize, PInfoRec recN) +{ + StartAdr = AStartAdr; + Size = ASize; + + StackSize = recN->procInfo->stackSize; + if (!StackSize) StackSize = 0x8000; + Stack = new ITEM[StackSize]; + + ErrAdr = 0; + Body = new TStringList; + Namer = new TNamer; + SavedContext = new TList; + BJLseq = new TList; + bjllist = new TList; + CmpStack = new TList; + Embedded = (recN->procInfo->flags & PF_EMBED); + EmbeddedList = new TStringList; + + BpBased = recN->procInfo->flags & PF_BPBASED; + LocBase = 0; + if (!BpBased) LocBase = StackSize; + LastResString = ""; +} +//--------------------------------------------------------------------------- +__fastcall TDecompileEnv::~TDecompileEnv() +{ + if (Stack) delete[] Stack; + if (Body) delete Body; + if (Namer) delete Namer; + if (SavedContext) delete SavedContext; + if (BJLseq) delete BJLseq; + if (bjllist) delete bjllist; + if (CmpStack) delete CmpStack; + if (EmbeddedList) delete EmbeddedList; +} +//--------------------------------------------------------------------------- +String __fastcall TDecompileEnv::GetLvarName(int Ofs, String Type) +{ + PLOCALINFO locInfo; + String _defaultName = String("lvar_") + Val2Str0(LocBase - Ofs); + + //Insert by ZGL + PInfoRec _recN = GetInfoRec(StartAdr); + if (_recN && _recN->procInfo) + { + if (_recN->procInfo->locals) + { + for (int n = 0; n < _recN->procInfo->locals->Count; n++) + { + locInfo = PLOCALINFO(_recN->procInfo->locals->Items[n]); + if (locInfo->Ofs == Ofs && locInfo->Name != "")//LocBase - Ofs + return locInfo->Name; + } + } + locInfo = _recN->procInfo->AddLocal(Ofs, 1, _defaultName, Type); + } + //////////////// + return _defaultName; +} +//--------------------------------------------------------------------------- +PDCONTEXT __fastcall TDecompileEnv::GetContext(DWORD Adr) +{ + int n; + PDCONTEXT ctx; + + for (n = 0; n < SavedContext->Count; n++) + { + ctx = (PDCONTEXT)SavedContext->Items[n]; + if (ctx->adr == Adr) return ctx; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::SaveContext(DWORD Adr) +{ + int n; + PDCONTEXT ctx; + + if (!GetContext(Adr)) + { + ctx = new DCONTEXT; + ctx->adr = Adr; + + for (n = 0; n < 8; n++) + { + ctx->gregs[n] = RegInfo[n]; + ctx->fregs[n] = FStack[n]; + } + SavedContext->Add((void*)ctx); + } +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::RestoreContext(DWORD Adr) +{ + int n; + PDCONTEXT ctx; + + ctx = GetContext(Adr); + if (ctx) + { + for (n = 0; n < 8; n++) + { + RegInfo[n] = ctx->gregs[n]; + FStack[n] = ctx->fregs[n]; + } + } +} +//--------------------------------------------------------------------------- +__fastcall TDecompiler::TDecompiler(TDecompileEnv* AEnv) +{ + WasRet = false; + Env = AEnv; + Stack = 0; + DeFlags = new BYTE[AEnv->Size + 1]; +} +//--------------------------------------------------------------------------- +__fastcall TDecompiler::~TDecompiler() +{ + if (Stack) delete[] Stack; + if (DeFlags) delete DeFlags; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SetDeFlags(BYTE* ASrc) +{ + memmove(DeFlags, ASrc, Env->Size + 1); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SetStop(DWORD Adr) +{ + DeFlags[Adr - Env->StartAdr] = 1; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::InitFlags() +{ + memset(DeFlags, 0, Env->Size + 1); + int _ap = Adr2Pos(Env->StartAdr); + for (int n = _ap; n < _ap + Env->Size + 1; n++) + { + if (IsFlagSet(cfLoc, n)) + { + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN) recN->counter = 0; + } + ClearFlag(cfPass, n); + } +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::ClearStop(DWORD Adr) +{ + DeFlags[Adr - Env->StartAdr] = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SetStackPointers(TDecompiler* ASrc) +{ + _TOP_ = ASrc->_TOP_; + _ESP_ = ASrc->_ESP_; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SetRegItem(int Idx, PITEM Val) +{ + int _idx; + + if (Idx >= 16) + { + _idx = Idx - 16; + Env->RegInfo[_idx].Size = 4; + } + else if (Idx >= 8) + { + _idx = Idx - 8; + Env->RegInfo[_idx].Size = 2; + } + else if (Idx >= 4) + { + _idx = Idx - 4; + Env->RegInfo[_idx].Size = 1; + } + else + { + _idx = Idx; + Env->RegInfo[_idx].Size = 1; + } + + Env->RegInfo[_idx].Flags = Val->Flags; + Env->RegInfo[_idx].Precedence = Val->Precedence; + Env->RegInfo[_idx].Offset = Val->Offset; + Env->RegInfo[_idx].IntValue = Val->IntValue; + Env->RegInfo[_idx].Value = Val->Value; + Env->RegInfo[_idx].Value1 = Val->Value1; + Env->RegInfo[_idx].Type = Val->Type; + Env->RegInfo[_idx].Name = Val->Name; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::GetRegItem(int Idx, PITEM Dst) +{ + int _idx; + + assert(Idx >= 0 && Idx < 24); + + if (Idx >= 16) + _idx = Idx - 16; + else if (Idx >= 8) + _idx = Idx - 8; + else if (Idx >= 4) + _idx = Idx - 4; + else + _idx = Idx; + + PITEM _src = &Env->RegInfo[_idx]; + Dst->Flags = _src->Flags; + Dst->Precedence = _src->Precedence; + Dst->Size = _src->Size; + Dst->Offset = _src->Offset; + Dst->IntValue = _src->IntValue; + Dst->Value = _src->Value; + Dst->Value1 = _src->Value1; + Dst->Type = _src->Type; + Dst->Name = _src->Name; +} +//--------------------------------------------------------------------------- +String __fastcall TDecompiler::GetRegType(int Idx) +{ + if (Idx >= 16) return Env->RegInfo[Idx - 16].Type; + if (Idx >= 8) return Env->RegInfo[Idx - 8].Type; + if (Idx >= 4) return Env->RegInfo[Idx - 4].Type; + return Env->RegInfo[Idx].Type; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::Push(PITEM Item) +{ + if (_ESP_ < 4) + { + Env->ErrAdr = CurProcAdr; + throw Exception("Stack!"); + } + _ESP_ -= 4; + Env->Stack[_ESP_] = *Item; + /* + Env->Stack[_ESP_].Flags = Item->Flags; + Env->Stack[_ESP_].Precedence = Item->Precedence; + Env->Stack[_ESP_].Size = Item->Size; + Env->Stack[_ESP_].Offset = Item->Offset; + Env->Stack[_ESP_].IntValue = Item->IntValue; + Env->Stack[_ESP_].Value = Item->Value; + Env->Stack[_ESP_].Type = Item->Type; + Env->Stack[_ESP_].Name = Item->Name; + */ +} +//--------------------------------------------------------------------------- +PITEM __fastcall TDecompiler::Pop() +{ + if (_ESP_ == Env->StackSize) + { + Env->ErrAdr = CurProcAdr; + throw Exception("Stack!"); + } + PITEM _item = &Env->Stack[_ESP_]; + _ESP_ += 4; + return _item; +} +//--------------------------------------------------------------------------- +//Get val from ST(idx) +PITEM __fastcall TDecompiler::FGet(int idx) +{ + PITEM _item = &Env->FStack[(_TOP_ + idx) & 7]; + return _item; +} +//--------------------------------------------------------------------------- +//Save val into ST(idx) +void __fastcall TDecompiler::FSet(int idx, PITEM val) +{ + int n = (_TOP_ + idx) & 7; + Env->FStack[n] = *val; + /* + Env->FStack[n].Flags = val->Flags; + Env->FStack[n].Precedence = val->Precedence; + Env->FStack[n].Size = val->Size; + Env->FStack[n].Offset = val->Offset; + Env->FStack[n].IntValue = val->IntValue; + Env->FStack[n].Value = val->Value; + Env->FStack[n].Type = val->Type; + Env->FStack[n].Name = val->Name; + */ +} +//--------------------------------------------------------------------------- +//Xchange ST(idx1) and ST(idx2) +void __fastcall TDecompiler::FXch(int idx1, int idx2) +{ + ITEM _tmp; + PITEM _item1 = FGet(idx1); + PITEM _item2 = FGet(idx2); + + _tmp.Flags = _item1->Flags; + _tmp.Precedence = _item1->Precedence; + _tmp.Size = _item1->Size; + _tmp.Offset = _item1->Offset; + _tmp.IntValue = _item1->IntValue; + _tmp.Value = _item1->Value; + _tmp.Type = _item1->Type; + _tmp.Name = _item1->Name; + + _item1->Flags = _item2->Flags; + _item1->Precedence = _item2->Precedence; + _item1->Size = _item2->Size; + _item1->Offset = _item2->Offset; + _item1->IntValue = _item2->IntValue; + _item1->Value = _item2->Value; + _item1->Type = _item2->Type; + _item1->Name = _item2->Name; + + _item2->Flags = _tmp.Flags; + _item2->Precedence = _tmp.Precedence; + _item2->Size = _tmp.Size; + _item2->Offset = _tmp.Offset; + _item2->IntValue = _tmp.IntValue; + _item2->Value = _tmp.Value; + _item2->Type = _tmp.Type; + _item2->Name = _tmp.Name; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::FPush(PITEM val) +{ + _TOP_--; + _TOP_ &= 7; + FSet(0, val); +} +//--------------------------------------------------------------------------- +PITEM __fastcall TDecompiler::FPop() +{ + PITEM _item = FGet(0); + _TOP_++; + _TOP_ &= 7; + return _item; +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompiler::CheckPrototype(PInfoRec ARec) +{ + int n, _argsNum; + PARGINFO _argInfo; + + _argsNum = (ARec->procInfo->args) ? ARec->procInfo->args->Count : 0; + for (n = 0; n < _argsNum; n++) + { + _argInfo = (PARGINFO)ARec->procInfo->args->Items[n]; + if (_argInfo->TypeDef == "") return false; + } + if (ARec->kind == ikFunc && ARec->type == "") return false; + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompiler::Init(DWORD fromAdr) +{ + BYTE _kind, _retKind = 0, _callKind; + int n, _pos, _argsNum, _ndx, _rn, _size; + int _fromPos; + PInfoRec _recN, _recN1; + PARGINFO _argInfo; + ITEM _item; + String _retType, _typeDef; + + _fromPos = Adr2Pos(fromAdr); assert(_fromPos >= 0); + //Imports not decompile + if (IsFlagSet(cfImport, _fromPos)) return true; + _recN = GetInfoRec(fromAdr); + if (!CheckPrototype(_recN)) return false; + _retType = _recN->type; + //Check that function return type is given + if (_recN->kind == ikFunc) _retKind = GetTypeKind(_retType, &_size); + //Init registers + InitItem(&_item); + for (n = 16; n < 24; n++) + { + SetRegItem(n, &_item); + } + + //Init Env->Stack + _ESP_ = Env->StackSize; + //Init floating registers stack + _TOP_ = 0; + for (n = 0; n < 8; n++) + { + FSet(n, &_item); + } + + _callKind = _recN->procInfo->flags & 7; + + //Arguments + _argsNum = (_recN->procInfo->args) ? _recN->procInfo->args->Count : 0; + if (_callKind == 0)//fastcall + { + _ndx = 0; + for (n = 0; n < _argsNum; n++) + { + _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; + InitItem(&_item); + _item.Flags = IF_ARG; + if (_argInfo->Tag == 0x22) _item.Flags |= IF_VAR; + _kind = GetTypeKind(_argInfo->TypeDef, &_size); + _item.Type = _argInfo->TypeDef; + _item.Name = GetArgName(_argInfo); + _item.Value = _item.Name; + + if (_kind == ikFloat && _argInfo->Tag != 0x22) + { + _size = _argInfo->Size; + while (_size) + { + Push(&_item); + _size -= 4; + } + continue; + } + //eax, edx, ecx + if (_ndx >= 0 && _ndx <= 2) + { + if (_ndx) + _rn = 19 - _ndx; + else + _rn = 16; + + SetRegItem(_rn, &_item); + _ndx++; + } + else + Push(&_item); + } + //ret value + if (_retKind == ikLString || _retKind == ikRecord) + { + InitItem(&_item); + _item.Flags = IF_ARG | IF_VAR; + _item.Type = _retType; + _item.Name = "Result"; + _item.Value = _item.Name; + + //eax, edx, ecx + if (_ndx >= 0 && _ndx <= 2) + { + if (_ndx) + _rn = 19 - _ndx; + else + _rn = 16; + + SetRegItem(_rn, &_item); + _ndx++; + } + else + Push(&_item); + } + } + else if (_callKind == 3 || _callKind == 1)//stdcall, cdecl + { + //Arguments in reverse order + for (n = _argsNum - 1; n >= 0; n--) + { + _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; + InitItem(&_item); + _item.Flags = IF_ARG; + if (_argInfo->Tag == 0x22) _item.Flags |= IF_VAR; + _item.Type = _argInfo->TypeDef; + _item.Name = GetArgName(_argInfo); + _item.Value = _item.Name; + Push(&_item); + } + } + else if (_callKind == 2)//pascal + { + for (n = 0; n < _argsNum; n++) + { + _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; + InitItem(&_item); + _item.Flags = IF_ARG; + if (_argInfo->Tag == 0x22) _item.Flags |= IF_VAR; + _item.Type = _argInfo->TypeDef; + _item.Name = GetArgName(_argInfo); + _item.Value = _item.Name; + Push(&_item); + } + } + //Push ret address + InitItem(&_item); + Push(&_item); + //Env->BpBased = _recN->procInfo->flags & PF_BPBASED; + //Env->LocBase = 0; + //if (!Env->BpBased) Env->LocBase = _ESP_; + //Env->LastResString = ""; + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::OutputSourceCodeLine(String line) +{ + int spaceNum = TAB_SIZE * Indent; + memset(StringBuf, ' ', spaceNum); + int len = sprintf(StringBuf + spaceNum, "%s", line.c_str()); + + FMain_11011981->lbSourceCode->Items->Add(String(StringBuf)); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::OutputSourceCode() +{ + bool _end; + String line, nextline; + + Alarm = False; + FMain_11011981->lbSourceCode->Clear(); Indent = 0; + for (int n = 0; n < Body->Count; n++) + { + line = Body->Strings[n]; + if (n < Body->Count - 1) + nextline = Body->Strings[n + 1]; + else + nextline = ""; + + if (line != "" && line[1] == '/' && line.Pos("??? And ???")) Alarm = True; + + if (SameText(line, "begin") || SameText(line, "try") || SameText(line, "repeat") || line.Pos("case ") > 0) + { + if (SameText(line, "begin")) line += "//" + String(Indent); + OutputSourceCodeLine(line); + Indent++; + continue; + } + + if (SameText(line, "finally") || SameText(line, "except")) + { + Indent--; + if (Indent < 0) Indent = 0; + line += "//" + String(Indent); + OutputSourceCodeLine(line); + Indent++; + continue; + } + + if (SameText(line, "end") || SameText(line, "until")) + { + _end = SameText(line, "end"); + Indent--; + if (Indent < 0)Indent = 0; + if (!SameText(nextline, "else")) line += ";"; + if (_end) line += "//" + String(Indent); + OutputSourceCodeLine(line); + continue; + } + OutputSourceCodeLine(line); + } +} +//--------------------------------------------------------------------------- +//Embedded??? +void __fastcall TDecompileEnv::DecompileProc() +{ + EmbeddedList->Clear(); + TDecompiler* De = new TDecompiler(this); + if (!De->Init(StartAdr)) + { + delete De; + throw Exception("Prototype is not completed"); + } + De->InitFlags(); + De->SetStop(StartAdr + Size); + + //add prototype + PInfoRec _recN = GetInfoRec(StartAdr); + ProcName = _recN->GetName(); + AddToBody(_recN->MakePrototype(StartAdr, true, false, false, true, false)); + + //add vars -- Insert by ZGL + if (_recN->procInfo->locals && _recN->procInfo->locals->Count > 0) + { + for (int n = 0; n < _recN->procInfo->locals->Count; n++) + { + PLOCALINFO locInfo = PLOCALINFO(_recN->procInfo->locals->Items[n]); + GetLvarName(locInfo->Ofs, locInfo->TypeDef); + } + } + if (_recN->procInfo->locals && _recN->procInfo->locals->Count > 0) + { + AddToBody("var"); + for (int n = 0; n < _recN->procInfo->locals->Count; n++) + { + PLOCALINFO locInfo = PLOCALINFO(_recN->procInfo->locals->Items[n]); + String line = " " + GetLvarName(locInfo->Ofs, locInfo->TypeDef) + ":" + locInfo->TypeDef + ";"; + AddToBody(line); + } + } + /////////////////////////// + + AddToBody("begin"); + if (StartAdr != EP) + { + if (_recN->kind == ikConstructor) + De->Decompile(StartAdr, CF_CONSTRUCTOR, 0); + else if (_recN->kind == ikDestructor) + De->Decompile(StartAdr, CF_DESTRUCTOR, 0); + else + De->Decompile(StartAdr, 0, 0); + } + else + { + De->Decompile(StartAdr, 0, 0); + } + AddToBody("end"); + delete De; +} +//--------------------------------------------------------------------------- +//BJL +bool __fastcall TDecompileEnv::GetBJLRange(DWORD fromAdr, DWORD* bodyBegAdr, DWORD* bodyEndAdr, DWORD* jmpAdr, PLoopInfo loopInfo) +{ + BYTE _op; + int _curPos, _instrLen, _brType; + DWORD _curAdr, _jmpAdr; + DISINFO _disInfo; + + *bodyEndAdr = 0; + *jmpAdr = 0; + _curPos = Adr2Pos(fromAdr); + assert(_curPos >= 0); + _curAdr = fromAdr; + + while (1) + { + if (_curAdr == *bodyBegAdr) break; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _curPos += _instrLen; _curAdr += _instrLen; + if (_disInfo.Branch) + { + if (IsFlagSet(cfSkip, _curPos - _instrLen)) continue; + if (!_disInfo.Conditional) return false; + _brType = BranchGetPrevInstructionType(_disInfo.Immediate, &_jmpAdr, loopInfo); + //jcc down + if (_brType == 1) + { + if (_disInfo.Immediate > *bodyBegAdr) + { + *bodyBegAdr = _disInfo.Immediate; + continue; + } + } + //simple if or jmp down + if (_brType == 0 || _brType == 3) + { + if (_disInfo.Immediate > *bodyEndAdr) + { + *bodyEndAdr = _disInfo.Immediate; + if (_brType == 3) *jmpAdr = _jmpAdr; + continue; + } + } + //jcc up + if (_brType == 2) + { + //if (_disInfo.Immediate > fromAdr) return false; + if (*bodyEndAdr == 0) + *bodyEndAdr = _disInfo.Immediate; + else if (*bodyEndAdr != _disInfo.Immediate) + throw Exception("GetBJLRange: unknown situation"); + } + //jmp up + if (_brType == 4) return false; + } + } + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::CreateBJLSequence(DWORD fromAdr, DWORD bodyBegAdr, DWORD bodyEndAdr) +{ + bool found; + BYTE _b; + int i, j, m, _curPos, _instrLen; + DWORD _curAdr, _adr; + PInfoRec _recN; + TBJL *_bjl, *_bjl1, *_bjl2; + TBJLInfo *_bjlInfo, *_bjlInfo1, *_bjlInfo2; + DISINFO _disInfo; + + BJLnum = 0; + + bjllist->Clear(); + BJLseq->Clear(); + _curPos = Adr2Pos(fromAdr); assert(_curPos >= 0); + _curAdr = fromAdr; + + while (1) + { + if (_curAdr == bodyBegAdr) + { + _bjl = new TBJL; + _bjl->branch = false; + _bjl->loc = true; + _bjl->type = BJL_LOC; + _bjl->address = bodyBegAdr; + _bjl->idx = 0; + bjllist->Add((void*)_bjl); + _bjlInfo = new TBJLInfo; + _bjlInfo->state = 'L'; + _bjlInfo->bcnt = 0; + _bjlInfo->address = bodyBegAdr; + _bjlInfo->dExpr = ""; + _bjlInfo->iExpr = ""; + BJLseq->Add((void*)_bjlInfo); + + _bjl = new TBJL; + _bjl->branch = false; + _bjl->loc = true; + _bjl->type = BJL_LOC; + _bjl->address = bodyEndAdr; + _bjl->idx = 0; + bjllist->Add((void*)_bjl); + _bjlInfo = new TBJLInfo; + _bjlInfo->state = 'L'; + _bjlInfo->bcnt = 0; + _bjlInfo->address = bodyEndAdr; + _bjlInfo->dExpr = ""; + _bjlInfo->iExpr = ""; + BJLseq->Add((void*)_bjlInfo); + break; + } + if (IsFlagSet(cfLoc, _curPos)) + { + _bjl = new TBJL; + _bjl->branch = false; + _bjl->loc = true; + _bjl->type = BJL_LOC; + _bjl->address = _curAdr; + _bjl->idx = 0; + bjllist->Add((void*)_bjl); + _bjlInfo = new TBJLInfo; + _bjlInfo->state = 'L'; + _bjlInfo->bcnt = 0; + _bjlInfo->address = _curAdr; + _bjlInfo->dExpr = ""; + _bjlInfo->iExpr = ""; + BJLseq->Add((void*)_bjlInfo); + } + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + if (_disInfo.Branch) + { + _bjl = new TBJL; + _bjl->branch = true; + _bjl->loc = false; + if (IsFlagSet(cfSkip, _curPos)) + _bjl->type = BJL_SKIP_BRANCH; + else + _bjl->type = BJL_BRANCH; + _bjl->address = _disInfo.Immediate; + _bjl->idx = 0; + bjllist->Add((void*)_bjl); + _bjlInfo = new TBJLInfo; + _bjlInfo->state = 'B'; + _bjlInfo->bcnt = 0; + _bjlInfo->address = _disInfo.Immediate; + + _b = *(Code + _curPos); + if (_b == 0xF) _b = *(Code + _curPos + 1); + _bjlInfo->dExpr = GetDirectCondition((_b & 0xF) + 'A'); + _bjlInfo->iExpr = GetInvertCondition((_b & 0xF) + 'A'); + BJLseq->Add((void*)_bjlInfo); + } + _curPos += _instrLen; _curAdr += _instrLen; + } + + for (i = 0, BJLmaxbcnt = 0; i < bjllist->Count; i++) + { + _bjl1 = (TBJL*)bjllist->Items[i]; + if (_bjl1->type == BJL_BRANCH || _bjl1->type == BJL_SKIP_BRANCH) + { + for (j = 0; j < bjllist->Count; j++) + { + _bjl2 = (TBJL*)bjllist->Items[j]; + if (_bjl2->type == BJL_LOC && _bjl1->address == _bjl2->address) + { + _bjlInfo = (TBJLInfo*)BJLseq->Items[j]; + _bjlInfo->bcnt++; + if (_bjlInfo->bcnt > BJLmaxbcnt) + BJLmaxbcnt = _bjlInfo->bcnt; + } + } + } + } + + while (1) + { + found = false; + for (i = 0; i < bjllist->Count; i++) + { + _bjl1 = (TBJL*)bjllist->Items[i]; + if (_bjl1->type == BJL_SKIP_BRANCH) + { + _adr = _bjl1->address; + bjllist->Delete(i); + delete _bjl1; + + _bjlInfo1 = (TBJLInfo*)BJLseq->Items[i]; + BJLseq->Delete(i); + delete _bjlInfo1; + + for (j = 0; j < bjllist->Count; j++) + { + _bjl2 = (TBJL*)bjllist->Items[j]; + if (_bjl2->type == BJL_LOC && _adr == _bjl2->address) + { + _bjlInfo2 = (TBJLInfo*)BJLseq->Items[j]; + _bjlInfo2->bcnt--; + + if (!_bjlInfo2->bcnt) + { + bjllist->Delete(j); + delete _bjl2; + BJLseq->Delete(j); + delete _bjlInfo2; + } + found = true; + break; + } + } + if (found) break; + } + } + if (!found) break; + } + + for (i = 0, m = 1, BJLmaxbcnt = 0; i < bjllist->Count; i++) + { + _bjl1 = (TBJL*)bjllist->Items[i]; + _bjl1->idx = i; + if (_bjl1->type == BJL_BRANCH) + { + _bjlInfo = (TBJLInfo*)BJLseq->Items[i]; + _bjlInfo->dExpr = "#" + String(m) + "#" + _bjlInfo->dExpr + "#" + String(m + 1) + "#"; + _bjlInfo->iExpr = "#" + String(m) + "#" + _bjlInfo->iExpr + "#" + String(m + 1) + "#"; + m += 2; + + for (j = 0; j < bjllist->Count; j++) + { + _bjl2 = (TBJL*)bjllist->Items[j]; + if (_bjl2->type == BJL_LOC && _bjl1->address == _bjl2->address) + { + _bjlInfo = (TBJLInfo*)BJLseq->Items[j]; + if (_bjlInfo->bcnt > BJLmaxbcnt) + BJLmaxbcnt = _bjlInfo->bcnt; + } + } + } + } + BJLnum = bjllist->Count; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::UpdateBJLList() +{ + bool found; + int i, j; + TBJL *_bjl, *_bjl1, *_bjl2; + TBJLInfo *_bjlInfo; + + while (1) + { + found = false; + for (i = 0; i < bjllist->Count; i++) + { + _bjl = (TBJL*)bjllist->Items[i]; + if (_bjl->type == BJL_USED) + { + bjllist->Delete(i); + found = true; + break; + } + } + if (!found) break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::BJLAnalyze() +{ + bool found = true; + int i, j, k, indx, no; + TBJL *_bjl; + TBJLInfo *_bjlInfo; + String sd, si; + int idx[MAXSEQNUM]; + char pattern[MAXSEQNUM]; + + UpdateBJLList(); + + while (found) + { + found = false; +//BM BM ... BM <=> BM (|| ... ||) +//BM 0 +//BM 1 +//... +//BM k-1 + for (k = BJLmaxbcnt; k >= 2; k--) + { + for (i = 0; i < bjllist->Count; i++) + { + if (!BJLGetIdx(idx, i, k)) continue; + for (j = 0; j < k; j++) pattern[j] = 'B'; + pattern[k] = 0; + if (!BJLCheckPattern1(pattern, i)) continue; + for (j = 0; j < k; j++) pattern[j] = '1'; + pattern[k] = 0; + if (!BJLCheckPattern2(pattern, i)) continue; + _bjl = (TBJL*)bjllist->Items[i]; + if ((indx = BJLFindLabel(_bjl->address, &no)) == -1) continue; + + BJLSeqSetStateU(idx, k - 1); + BJLListSetUsed(i, k - 1); + sd = ""; si = ""; + + for (j = 0; j < k; j++) + { + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[j]]; + ExprMerge(sd, _bjlInfo->dExpr, '|'); + ExprMerge(si, _bjlInfo->iExpr, '&'); + } + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[k - 1]]; + _bjlInfo->dExpr = sd; + _bjlInfo->iExpr = si; + + _bjlInfo = (TBJLInfo*)BJLseq->Items[indx]; + _bjl = (TBJL*)bjllist->Items[no]; + _bjlInfo->bcnt -= k - 1; + if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) _bjl->type = BJL_USED; + + UpdateBJLList(); + found = true; + break; + } + if (found) break; + } + if (found) continue; +//BN BM @N <=> BM (&&) +//BN 0 +//BM 1 +//@N 2 + for (i = 0; i < bjllist->Count; i++) + { + if (!BJLGetIdx(idx, i, 3)) continue; + if (!BJLCheckPattern1("BBL", i)) continue; + if (!BJLCheckPattern2("101", i)) continue; + if (BJLCheckPattern2("111", i)) continue; //check that N != M + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; + _bjlInfo->state = 'U'; + _bjl = (TBJL*)bjllist->Items[i]; + _bjl->type = BJL_USED; + + sd = ""; si = ""; + ExprMerge(sd, _bjlInfo->iExpr, '&'); + ExprMerge(si, _bjlInfo->dExpr, '|'); + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[1]]; + ExprMerge(sd, _bjlInfo->dExpr, '&'); + ExprMerge(si, _bjlInfo->iExpr, '|'); + + _bjlInfo->dExpr = sd; + _bjlInfo->iExpr = si; + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[2]]; + _bjl = (TBJL*)bjllist->Items[i + 2]; + _bjlInfo->bcnt--; + if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) _bjl->type = BJL_USED; + + UpdateBJLList(); + found = true; + break; + } + if (found) continue; +//BN @N <=> if (~BN) +//BN 0 if { +//@N 1 } + for (i = 0; i < bjllist->Count; i++) + { + if (!BJLGetIdx(idx, i, 2)) continue; + if (!BJLCheckPattern1("BL", i)) continue; + if (!BJLCheckPattern2("11", i)) continue; + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; + _bjlInfo->state = 'I'; + _bjlInfo->result = _bjlInfo->iExpr; + _bjl = (TBJL*)bjllist->Items[i]; + _bjl->branch = false; + _bjl->type = BJL_USED; + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[1]]; + _bjl = (TBJL*)bjllist->Items[i + 1]; + _bjlInfo->bcnt--; + if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) _bjl->type = BJL_USED; + + UpdateBJLList(); + found = true; + break; + } + if (found) continue; +//BN BM @N @M <=> if (BN || ~BM) +//BN 0 if { +//BM 1 +//@N 2 +//@M 3 } k = 1 + for (i = 0; i < bjllist->Count; i++) + { + if (!BJLGetIdx(idx, i, 4)) continue; + if (!BJLCheckPattern1("BBLL", i)) continue; + if (!BJLCheckPattern2("1010", i)) continue; + if (!BJLCheckPattern2("0101", i)) continue; + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; + _bjlInfo->state = 'I'; + sd = _bjlInfo->dExpr; + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[1]]; + ExprMerge(sd, _bjlInfo->iExpr, '|'); + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; + _bjlInfo->result = sd; + + BJLSeqSetStateU(idx, 2); + BJLListSetUsed(i, 2); + + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[2]]; + _bjl = (TBJL*)bjllist->Items[i + 2]; + _bjlInfo->bcnt--; + if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) _bjl->type = BJL_USED; + _bjl = (TBJL*)bjllist->Items[i + 3]; + _bjlInfo->bcnt--; + if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) _bjl->type = BJL_USED; + + UpdateBJLList(); + found = true; + break; + } + if (found) continue; + } +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompileEnv::BJLGetIdx(int* idx, int from, int num) +{ + TBJL *_bjl; + + for (int k = 0; k < num; k++) + { + if (from + k < bjllist->Count) + { + _bjl = (TBJL*)bjllist->Items[from + k]; + idx[k] = _bjl->idx; + } + else + { + return false; + } + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompileEnv::BJLCheckPattern1(char* t, int from) +{ + TBJL *_bjl; + + for (int k = 0; k < strlen(t); k++) + { + if (from + k >= bjllist->Count) return false; + _bjl = (TBJL*)bjllist->Items[from + k]; + if (t[k] == 'B' && !_bjl->branch) return false; + if (t[k] == 'L' && !_bjl->loc) return false; + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompileEnv::BJLCheckPattern2(char* t, int from) +{ + int _address = -1; + TBJL *_bjl; + + for (int k = 0; k < strlen(t); k++) + { + if (from + k >= bjllist->Count) return false; + if (t[k] == '1') + { + _bjl = (TBJL*)bjllist->Items[from + k]; + if (_address == -1) + { + _address = _bjl->address; + continue; + } + if (_bjl->address != _address) return false; + } + } + return true; +} +//--------------------------------------------------------------------------- +int __fastcall TDecompileEnv::BJLFindLabel(int address, int* no) +{ + TBJL *_bjl; + + *no = -1; + for (int k = 0; k < bjllist->Count; k++) + { + _bjl = (TBJL*)bjllist->Items[k]; + if (_bjl->loc && _bjl->address == address) + { + *no = k; + return _bjl->idx; + } + } + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::BJLSeqSetStateU(int* idx, int num) +{ + TBJLInfo *_bjlInfo; + + for (int k = 0; k < num; k++) + { + if (idx[k] < 0 || idx[k] >= BJLseq->Count) break; + _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[k]]; + _bjlInfo->state = 'U'; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::BJLListSetUsed(int from, int num) +{ + TBJL *_bjl; + + for (int k = 0; k < num; k++) + { + if (from + k >= bjllist->Count) break; + _bjl = (TBJL*)bjllist->Items[from + k]; + _bjl->type = BJL_USED; + } +} +//--------------------------------------------------------------------------- +char __fastcall TDecompileEnv::ExprGetOperation(String s) +{ + char c; + int n = 0; + + for (int k = 1; k <= s.Length(); k++) + { + c = s[k]; + if (c == '(') + { + n++; + continue; + } + if (c == ')') + { + n--; + continue; + } + if ((c == '&' || c == '|') && !n) return c; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::ExprMerge(String& dst, String src, char op)//dst = dst op src, op = '|' or '&' +{ + char op1, op2; + + if (dst == "") {dst = src; return;} + + op1 = ExprGetOperation(dst); + op2 = ExprGetOperation(src); + + if (op == '|') + { + if (op1 == 0) + { + if (op2 == 0) {dst = dst + " || " + src; return;} + if (op2 == '|') {dst = dst + " || " + src; return;} + if (op2 == '&') {dst = dst + " || (" + src + ")"; return;} + } + if (op1 == '|') + { + if (op2 == 0) {dst = dst + " || " + src; return;} + if (op2 == '|') {dst = dst + " || " + src; return;} + if (op2 == '&') {dst = dst + " || (" + src + ")"; return;} + } + if (op1 == '&') + { + if (op2 == 0) {dst = "(" + dst + ") || " + src; return;} + if (op2 == '|') {dst = "(" + dst + ") || " + src; return;} + if (op2 == '&') {dst = "(" + dst + ") || (" + src + ")"; return;} + } + } + if (op == '&') + { + if (op1 == 0) + { + if (op2 == 0) {dst = dst + " && " + src; return;} + if (op2 == '|') {dst = dst + " && (" + src + ")"; return;} + if (op2 == '&') {dst = dst + " && " + src; return;} + } + if (op1 == '|') + { + if (op2 == 0) {dst = "(" + dst + ") && " + src; return;} + if (op2 == '|') {dst = "(" + dst + ") && (" + src + ")"; return;} + if (op2 == '&') {dst = "(" + dst + ") && " + src; return;} + } + if (op1 == '&') + { + if (op2 == 0) {dst = dst + " && " + src; return;} + if (op2 == '|') {dst = dst + " && (" + src + ")"; return;} + if (op2 == '&') {dst = dst + " && " + src; return;} + } + } +} +//--------------------------------------------------------------------------- +String __fastcall TDecompileEnv::PrintBJL() +{ + int n, m, k; + String _result = ""; + CMPITEM *_cmpItem; + TBJLInfo *_bjlInfo; + + for (n = 0; n < BJLseq->Count; n++) + { + _bjlInfo = (TBJLInfo*)BJLseq->Items[n]; + if (_bjlInfo->state == 'I') + { + _result = _bjlInfo->result; + for (m = 0, k = 1; m < CmpStack->Count; m++) + { + _cmpItem = (CMPITEM*)CmpStack->Items[m]; + _result = AnsiReplaceText(_result, "#" + String(k) + "#", "(" + _cmpItem->L + " "); k++; + _result = AnsiReplaceText(_result, "#" + String(k) + "#", " " + _cmpItem->R + ")"); k++; + } + break; + } + } + _result = AnsiReplaceText(_result, "||", "Or"); + _result = AnsiReplaceText(_result, "&&", "And"); + return _result; +} +//--------------------------------------------------------------------------- +DWORD __fastcall TDecompiler::Decompile(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo) +{ + bool _cmp, _immInt64Val, _fullSim; + BYTE _op; + DWORD _dd, _curAdr, _branchAdr, _sAdr, _jmpAdr, _endAdr, _adr; + DWORD _begAdr; + int n, _kind, _skip1, _skip2, _size, _elSize, _procSize; + int _fromPos, _curPos, _endPos, _instrLen, _instrLen1, _num, _regIdx, _pos, _sPos; + int _decPos, _cmpRes, _varidx, _brType, _mod, _div; + int _bytesToSkip, _bytesToSkip1, _bytesToSkip2, _bytesToSkip3; + __int64 _int64Val; + PInfoRec _recN, _recN1; + PLoopInfo _loopInfo; + PXrefRec _recX; + ITEM _item, _item1, _item2; + String _line, _comment, _name, _typeName; + DISINFO _disInfo; + TDecompiler *de; + + _fromPos = Adr2Pos(fromAdr); + + _line = "//" + Val2Str8(fromAdr); + if (IsFlagSet(cfPass, _fromPos)) + { + _line += "??? And ???"; + //return fromAdr; + } + Env->AddToBody(_line); + + _curPos = _fromPos; _curAdr = fromAdr; + _procSize = GetProcSize(Env->StartAdr); + + while (1) + { +//!!! +if (_curAdr == 0x007422A4) +_curAdr = _curAdr; + //End of decompilation + if (DeFlags[_curAdr - Env->StartAdr] == 1) + { + SetFlag(cfPass, _fromPos); + break; + } + //@TryFinallyExit + if (IsFlagSet(cfFinallyExit, _curPos)) + { + _pos = _curPos; _adr = _curAdr; _num = 0; + while (IsFlagSet(cfFinallyExit, _pos)) + { + ClearFlag(cfFinallyExit, _pos);//to avoid infinity recursion + _pos++; _adr++; _num++; + } + + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_adr); + try + { + _curAdr = de->Decompile(_curAdr, 0, 0); + //Env->AddToBody("Exit;"); + } + catch(Exception &exception) + { + delete de; + throw Exception("FinallyExit->" + exception.Message); + } + delete de; + + SetFlags(cfFinallyExit, _curPos, _num);//restore flags + _curPos = _pos; _curAdr = _adr; + continue; + } + //Try + if (IsFlagSet(cfTry, _curPos)) + { + try + { + _curAdr = DecompileTry(_curAdr, flags, loopInfo); + } + catch(Exception &exception) + { + throw Exception("Decompile->" + exception.Message); + } + _curPos = Adr2Pos(_curAdr); + continue; + } + + if (IsFlagSet(cfLoop, _curPos)) + { + _recN = GetInfoRec(_curAdr); + if (IsFlagSet(cfFrame, _curPos)) + { + if (_recN && _recN->xrefs->Count == 1) + { + _recX = (PXrefRec)_recN->xrefs->Items[0]; + _endPos = GetNearestUpInstruction(Adr2Pos(_recX->adr + _recX->offset)); _endAdr = Pos2Adr(_endPos); + //Check instructions between _curAdr and _endAdr (must be push, add or sub to full simulation) + _fullSim = true; _pos = _curPos; _adr = _curAdr; + while (1) + { + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op != OP_PUSH && _op != OP_ADD && _op != OP_SUB) + { + _fullSim = false; + break; + } + _pos += _instrLen; _adr += _instrLen; + if (_pos >= _endPos) break; + } + //Full simulation + if (_fullSim) + { + //Get instruction at _endAdr + _pos = _endPos; _adr = _endAdr; + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //dec reg in frame - full simulate + if (_op == OP_DEC && _disInfo.OpType[0] == otREG) + { + _regIdx = _disInfo.OpRegIdx[0]; + GetRegItem(_regIdx, &_item); + //Save dec position + _decPos = _pos; + + _num = _item.IntValue; + //next instruction is jne + _pos += _instrLen; + _adr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + _branchAdr = _disInfo.Immediate; + //Save position and address + _sPos = _pos + _instrLen; + _sAdr = _adr + _instrLen; + + for (n = 0; n < _num; n++) + { + _adr = _branchAdr; + _pos = Adr2Pos(_adr); + while (1) + { + if (_pos == _decPos) break; + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &DisInfo, 0); + _op = Disasm.GetOp(DisInfo.Mnem); + if (_op == OP_PUSH) SimulatePush(_adr, true); + if (_op == OP_ADD || _op == OP_SUB) SimulateInstr2(_adr, _op); + _pos += _instrLen; + _adr += _instrLen; + } + } + //reg = 0 after cycle + InitItem(&_item); + _item.Flags |= IF_INTVAL; + SetRegItem(_regIdx, &_item); + _curPos = _sPos; + _curAdr = _sAdr; + continue; + } + } + } + } + else//loop + { + //Count xrefs from above + for (n = 0, _num = 0; n < _recN->xrefs->Count; n++) + { + _recX = (PXrefRec)_recN->xrefs->Items[n]; + if (_recX->adr + _recX->offset < _curAdr) _num++; + } + if (_recN && _recN->counter < _recN->xrefs->Count - _num) + { + _recN->counter++; + _loopInfo = GetLoopInfo(_curAdr); + if (!_loopInfo) + { + Env->ErrAdr = _curAdr; + throw Exception("Control flow under construction"); + } + //for + if (_loopInfo->Kind == 'F') + { + _line = "for "; + if (_loopInfo->forInfo->NoVar) + { + _varidx = _loopInfo->forInfo->CntInfo.IdxValue; + //register + if (_loopInfo->forInfo->CntInfo.IdxType == itREG) + _line += GetDecompilerRegisterName(_varidx); + //local var + if (_loopInfo->forInfo->CntInfo.IdxType == itLVAR) + _line += Env->GetLvarName((int)_varidx, "Integer"); + } + else + { + _varidx = _loopInfo->forInfo->VarInfo.IdxValue; + //register + if (_loopInfo->forInfo->VarInfo.IdxType == itREG) + _line += GetDecompilerRegisterName(_varidx); + //local var + if (_loopInfo->forInfo->VarInfo.IdxType == itLVAR) + _line += Env->GetLvarName((int)_varidx, "Integer"); + } + _line += " := " + _loopInfo->forInfo->From + " "; + if (_loopInfo->forInfo->Down) _line += "down"; + _line += "to " + _loopInfo->forInfo->To + " do"; + Env->AddToBody(_line); + + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_loopInfo->forInfo->StopAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_curAdr, 0, _loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("Loop->" + exception.Message); + } + delete de; + if (_curAdr > _loopInfo->BreakAdr) + { + Env->ErrAdr = _curAdr; + throw Exception("Loop->desynchronization"); + } + _curAdr = _loopInfo->BreakAdr; + _curPos = Adr2Pos(_curAdr); + delete _loopInfo; + continue; + } + //while, repeat + else + { + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_loopInfo->BreakAdr); + try + { + if (_loopInfo->Kind == 'R') + Env->AddToBody("repeat"); + else + { + Env->AddToBody("while () do"); + Env->AddToBody("begin"); + } + _curAdr = de->Decompile(_curAdr, 0, _loopInfo); + if (_loopInfo->Kind == 'R') + Env->AddToBody("until"); + else + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("Loop->" + exception.Message); + } + delete de; + if (_curAdr > _loopInfo->BreakAdr) + { + Env->ErrAdr = _curAdr; + throw Exception("Loop->desynchronization"); + } + _curAdr = _loopInfo->BreakAdr; + _curPos = Adr2Pos(_curAdr); + delete _loopInfo; + continue; + } + } + } + } + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + //if (!_instrLen) + //{ + // Env->ErrAdr = _curAdr; + // throw Exception("Unknown instruction"); + //} + if (!_instrLen) + { + Env->AddToBody("???"); + _curPos++; _curAdr++; + continue; + } + + if (IsFlagSet(cfDSkip, _curPos)) + { + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + _dd = *((DWORD*)DisInfo.Mnem); + //skip wait, sahf + if (_dd == 'tiaw' || _dd == 'fhas') + { + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + _op = Disasm.GetOp(DisInfo.Mnem); + //cfSkip - skip instructions + if (IsFlagSet(cfSkip, _curPos)) + { + //Constructor or Destructor + if ((_op == OP_TEST || _op == OP_CMP || DisInfo.Call) && (flags & (CF_CONSTRUCTOR | CF_DESTRUCTOR))) + { + while (1) + { + //If instruction test or cmp - skip until loc (instruction at loc position need to be executed) + if ((_op == OP_TEST || _op == OP_CMP) && IsFlagSet(cfLoc, _curPos)) break; + _curPos += _instrLen; _curAdr += _instrLen; + //Skip @BeforeDestruction + if (DisInfo.Call && !IsFlagSet(cfSkip, _curPos)) break; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + if (!_instrLen) + { + Env->AddToBody("???"); + _curPos++; _curAdr++; + continue; + } + } + continue; + } + if ((flags & (CF_FINALLY | CF_EXCEPT))) + { + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (DisInfo.Call) + { + if (flags & CF_EXCEPT) + { + _recN = GetInfoRec(DisInfo.Immediate); + if (_recN->SameName("@DoneExcept")) + { + _curPos += _instrLen; _curAdr += _instrLen; + break; + } + } + } + } + + if (DisInfo.Branch) + { + _pos = Adr2Pos(DisInfo.Immediate); + if (DisInfo.Conditional) + { + _bytesToSkip = IsIntOver(_curAdr); + if (_bytesToSkip) + { + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + //Skip jns + if (_dd == 'snj') + { + _curAdr = DisInfo.Immediate; + _curPos = Adr2Pos(_curAdr); + continue; + } + } + //skip jmp + else + { + //Case without cmp + if (IsFlagSet(cfSwitch, _curPos)) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileCaseEnum(_curAdr, 0, loopInfo); + Env->AddToBody("end"); + _curPos = Adr2Pos(_curAdr); + continue; + } + //Some deoptimization! + if (0)//IsFlagSet(cfLoop, _pos) + { + _recN = GetInfoRec(DisInfo.Immediate); + if (_recN->xrefs) + { + for (n = 0; n < _recN->xrefs->Count; n++) + { + _recX = (PXrefRec)_recN->xrefs->Items[n]; + if (_recX->adr + _recX->offset == _curAdr && _recX->type == 'J') + { + SetFlag(cfLoop | cfLoc, _curPos); + _recN1 = GetInfoRec(_curAdr); + if (!_recN1) _recN1 = new InfoRec(_curPos, ikUnknown); + continue; + } + } + } + } + //jmp XXXXXXXX - End Of Decompilation? + if (DeFlags[DisInfo.Immediate - Env->StartAdr] == 1) + { + //SetFlag(cfPass, _fromPos); + //check Exit + if (IsExit(DisInfo.Immediate)) + Env->AddToBody("Exit;"); + //if jmp BreakAdr + if (loopInfo && loopInfo->BreakAdr == DisInfo.Immediate) + Env->AddToBody("Break;"); + _curPos += _instrLen; _curAdr += _instrLen; + break; + } + _curPos += _instrLen; _curAdr += _instrLen; + if (DeFlags[_curAdr - Env->StartAdr] == 1) + { + //if stop flag at this point - check Exit + if (IsExit(DisInfo.Immediate)) + Env->AddToBody("Exit;"); + //if jmp BreakAdr + if (loopInfo && loopInfo->BreakAdr == DisInfo.Immediate) + Env->AddToBody("Break;"); + } + continue; + } + } + + if (DisInfo.Call) + { + _recN = GetInfoRec(DisInfo.Immediate); + if (_recN) + { + //Inherited + if ((flags & (CF_CONSTRUCTOR | CF_DESTRUCTOR)) && IsValidCodeAdr(DisInfo.Immediate)) + { + GetRegItem(16, &_item); + if (SameText(_item.Value, "Self")) //eax=Self + { + if (_recN->kind == ikConstructor || _recN->kind == ikDestructor) + { + SimulateInherited(DisInfo.Immediate); + Env->AddToBody("inherited;"); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + } + //Other case (not constructor and destructor) + if (IsInheritsByProcName(Env->ProcName, _recN->GetName())) + { + SimulateInherited(DisInfo.Immediate); + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Name = "EAX"; + _item.Type = _recN->type; + SetRegItem(16, &_item); + Env->AddToBody("EAX := inherited " + ExtractProcName(Env->ProcName) + ";"); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + //true - CMP + _cmp = SimulateCall(_curAdr, DisInfo.Immediate, _instrLen, 0, 0); + if (_cmp) + { + _sPos = _curPos; _sAdr = _curAdr; + _curPos += _instrLen; _curAdr += _instrLen; + _cmpRes = GetCmpInfo(_curAdr); + CmpInfo.O = CmpOp; + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue;//??? + } + + if (_cmpRes == CMP_BRANCH) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + //jcc up + if (_disInfo.Immediate < _curAdr) + { + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + + if (_op == OP_MOV) + { + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (DisInfo.Ret) + { + _ESP_ += 4; + _curPos += _instrLen; _curAdr += _instrLen; + //End of proc + if (_procSize && _curPos - _fromPos < _procSize) + Env->AddToBody("Exit;"); + WasRet = true; + SetFlag(cfPass, Adr2Pos(fromAdr)); + break; + //continue; + } + if (_op == OP_PUSH) + { + _bytesToSkip1 = IsInt64ComparisonViaStack1(_curAdr, &_skip1, &_endAdr); + _bytesToSkip2 = IsInt64ComparisonViaStack2(_curAdr, &_skip1, &_skip2, &_endAdr); + if (_bytesToSkip1 + _bytesToSkip2 == 0) + { + SimulatePush(_curAdr, !IsFlagSet(cfFrame, _curPos)); + _curPos += _instrLen; _curAdr += _instrLen; + } + else + { + //Save position and address + _sPos = _curPos; _sAdr = _curAdr; + + //Simulate push + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulatePush(_curAdr, true); + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulatePush(_curAdr, true); + _curPos += _instrLen; _curAdr += _instrLen; + + //Decompile until _skip1 + SetStop(_endAdr); + Decompile(_curAdr, flags, 0); + + if (_bytesToSkip1) + _cmpRes = GetCmpInfo(_sAdr + _bytesToSkip1); + else + _cmpRes = GetCmpInfo(_sAdr + _bytesToSkip2); + + //Simulate 2nd cmp instruction + _curPos = _sPos + _skip1; _curAdr = _sAdr + _skip1; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr2(_curAdr, OP_CMP); + _curPos += _instrLen; _curAdr += _instrLen; + //Simulate pop + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulatePop(_curAdr); + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulatePop(_curAdr); + + if (_bytesToSkip1) + { + _curPos = _sPos + _bytesToSkip1; _curAdr = _sAdr + _bytesToSkip1; + } + else + { + _curPos = _sPos + _bytesToSkip2; _curAdr = _sAdr + _bytesToSkip2; + } + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_cmpRes == CMP_BRANCH) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + //jcc up + if (_disInfo.Immediate < _curAdr) + { + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + } + } + continue; + } + if (_op == OP_POP) + { + SimulatePop(_curAdr); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_XOR) + { + if (!IsXorMayBeSkipped(_curAdr)) SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_CMP || (DisInfo.Float && _dd == 'mocf')) + { + //Save position and address + _sPos = _curPos; _sAdr = _curAdr; + _bytesToSkip = IsBoundErr(_curAdr); + if (_bytesToSkip) + { + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + if (IsFlagSet(cfSwitch, _curPos)) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileCaseEnum(_curAdr, 0, loopInfo); + Env->AddToBody("end"); + _curPos = Adr2Pos(_curAdr); + continue; + } + _bytesToSkip = IsInlineLengthCmp(_curAdr); + if (_bytesToSkip) + { + GetMemItem(_curAdr, &_item, 0); + _line = _item.Name + " := Length("; + if (_item.Name != "") + _line += _item.Name; + else + _line += _item.Value; + _line += ");"; + Env->AddToBody(_line); + + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); + if (_endAdr) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); + Env->AddToBody("end"); + //_curAdr = _endAdr; + _curPos = Adr2Pos(_curAdr); + continue; + } + //skip current instruction (cmp) + _curPos += _instrLen; _curAdr += _instrLen; + + if (!DisInfo.Float) + { + _bytesToSkip1 = 0;//IsInt64Equality(_sAdr, &_skip1, &_skip2, &_immInt64Val, &_int64Val); + _bytesToSkip2 = 0;//IsInt64NotEquality(_sAdr, &_skip1, &_skip2, &_immInt64Val, &_int64Val); + _bytesToSkip3 = IsInt64Comparison(_sAdr, &_skip1, &_skip2, &_immInt64Val, &_int64Val); + if (_bytesToSkip1 + _bytesToSkip2 + _bytesToSkip3 == 0) + { + _cmpRes = GetCmpInfo(_curAdr); + SimulateInstr2(_sAdr, _op); + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + //int64 comparison + else + { + if (_bytesToSkip1) + { + _cmpRes = GetCmpInfo(_sAdr + _skip2); + _curPos = _sPos + _skip1; _curAdr = _sAdr + _skip1; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr2(_curAdr, _op); + if (_immInt64Val) CmpInfo.R = IntToStr(_int64Val) + "{" + IntToHex(_int64Val, 0) + "}"; + _curPos = _sPos + _bytesToSkip1; _curAdr = _sAdr + _bytesToSkip1; + } + else if (_bytesToSkip2) + { + _cmpRes = GetCmpInfo(_sAdr + _skip2); + _curPos = _sPos + _skip1; _curAdr = _sAdr + _skip1; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr2(_curAdr, _op); + if (_immInt64Val) CmpInfo.R = IntToStr(_int64Val) + "{" + IntToHex(_int64Val, 0) + "}"; + _curPos = _sPos + _bytesToSkip2; _curAdr = _sAdr + _bytesToSkip2; + } + else//_bytesToSkip3 + { + _cmpRes = GetCmpInfo(_sAdr + _skip2); + _curPos = _sPos + _skip1; _curAdr = _sAdr + _skip1; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr2(_curAdr, _op); + if (_immInt64Val) CmpInfo.R = IntToStr(_int64Val) + "{" + IntToHex(_int64Val, 0) + "}"; + _curPos = _sPos + _bytesToSkip3; _curAdr = _sAdr + _bytesToSkip3; + } + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + } + else + { + //skip until branch or set + while (1) + { + _instrLen1 = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_disInfo.Branch || _op == OP_SET) break; + _curPos += _instrLen1; _curAdr += _instrLen1; + } + + _cmpRes = GetCmpInfo(_curAdr); + //SimulateFloatInstruction(_sAdr); + + if (flags & CF_BJL) + { + SimulateFloatInstruction(_sAdr); + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + _curPos += _instrLen1; _curAdr += _instrLen1; + continue; + } + } + if (_cmpRes == CMP_FAILED) continue; + + if (_cmpRes == CMP_BRANCH) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + //Exit + if (IsExit(_disInfo.Immediate)) + { + if (DisInfo.Float) SimulateFloatInstruction(_sAdr); + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Exit;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + //jcc up + if (_disInfo.Immediate < _curAdr) + { + if (DisInfo.Float) SimulateFloatInstruction(_sAdr); + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + //jcc at BreakAdr + if (loopInfo && loopInfo->BreakAdr == _disInfo.Immediate) + { + if (DisInfo.Float) SimulateFloatInstruction(_sAdr); + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Break;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + //jcc at forInfo->StopAdr + if (loopInfo && loopInfo->forInfo && loopInfo->forInfo->StopAdr == _disInfo.Immediate) + { + if (DisInfo.Float) SimulateFloatInstruction(_sAdr); + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + if (_op == OP_TEST || _op == OP_BT) + { + //Save address + _sAdr = _curAdr; + _bytesToSkip = IsInlineLengthTest(_curAdr); + if (_bytesToSkip) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "Length(" + _item.Value + ")"; + _item.Type = "Integer"; + SetRegItem(DisInfo.OpRegIdx[0], &_item); + + _line = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " := Length(" + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + ");"; + Env->AddToBody(_line); + + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + _bytesToSkip = IsInlineDiv(_curAdr, &_div); + if (_bytesToSkip) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = GetString(&_item, PRECEDENCE_MULT) + " Div " + String(_div); + _item.Type = "Integer"; + SetRegItem(DisInfo.OpRegIdx[0], &_item); + + _line = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " := " + _item.Value + ";"; + Env->AddToBody(_line); + + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + _bytesToSkip = IsCopyDynArrayToStack(_curAdr); + if (_bytesToSkip) + { + Env->AddToBody("//Copy dynamic array to stack"); + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + + _cmpRes = GetCmpInfo(_curAdr + _instrLen); + SimulateInstr2(_sAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + + if (_cmpRes == CMP_BRANCH) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + //jcc up + if (_disInfo.Immediate < _curAdr) + { + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + //jcc at BreakAdr + if (loopInfo && loopInfo->BreakAdr == _disInfo.Immediate) + { + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Break;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + //jcc at forInfo->StopAdr + if (loopInfo && loopInfo->forInfo && loopInfo->forInfo->StopAdr == _disInfo.Immediate) + { + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + if (_op == OP_LEA) + { + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_ADD) + { + _bytesToSkip = IsIntOver(_curAdr + _instrLen); + + _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); + if (_endAdr) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); + Env->AddToBody("end"); + //_curAdr = _endAdr; + _curPos = Adr2Pos(_curAdr); + continue; + } + //Next switch + if (IsFlagSet(cfSwitch, _curPos + _instrLen)) + { + n = -DisInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + GetRegItem(_disInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(_disInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileCaseEnum(_curAdr, n, loopInfo); + Env->AddToBody("end"); + _curPos = Adr2Pos(_curAdr); + continue; + } + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen + _bytesToSkip; _curAdr += _instrLen + _bytesToSkip; + continue; + } + if (_op == OP_SUB) + { + //Save address + _sAdr = _curAdr; + _bytesToSkip = IsIntOver(_curAdr + _instrLen); + + _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); + if (_endAdr) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); + Env->AddToBody("end"); + //_curAdr = _endAdr; + _curPos = Adr2Pos(_curAdr); + continue; + } + //Next switch + if (IsFlagSet(cfSwitch, _curPos + _instrLen)) + { + n = DisInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + GetRegItem(_disInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(_disInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileCaseEnum(_curAdr, n, loopInfo); + Env->AddToBody("end"); + _curPos = Adr2Pos(_curAdr); + continue; + } + _cmpRes = GetCmpInfo(_curAdr + _instrLen); + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + + if (_bytesToSkip) + { + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + + if (_cmpRes == CMP_BRANCH) + { + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + continue; + } + if (_op == OP_AND) + { + _bytesToSkip = IsInlineMod(_curAdr, &_mod); + if (_bytesToSkip) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = _item.Value + " mod " + String(_mod); + _item.Type = "Integer"; + SetRegItem(DisInfo.OpRegIdx[0], &_item); + + _line = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " := " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " mod " + String(_mod); + Env->AddToBody(_line); + + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + _cmpRes = GetCmpInfo(_curAdr + _instrLen); + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_cmpRes == CMP_BRANCH) + { + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + continue; + } + if (_op == OP_OR) + { + _cmpRes = GetCmpInfo(_curAdr + _instrLen); + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_cmpRes == CMP_BRANCH) + { + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + continue; + } + if (_op == OP_ADC || _op == OP_SBB) + { + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_SAL || _op == OP_SHL) + { + _bytesToSkip = IsInt64Shl(_curAdr); + if (_bytesToSkip) + { + DisInfo.OpNum = 2; + DisInfo.OpType[1] = otIMM; + } + else + { + _bytesToSkip = _instrLen; + } + SimulateInstr2(_curAdr, _op); + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + if (_op == OP_SAR || _op == OP_SHR) + { + _bytesToSkip = IsInt64Shr(_curAdr); + if (_bytesToSkip) + { + DisInfo.OpNum = 2; + DisInfo.OpType[1] = otIMM; + } + else + { + _bytesToSkip = _instrLen; + } + SimulateInstr2(_curAdr, _op); + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + continue; + } + if (_op == OP_NEG) + { + SimulateInstr1(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_NOT) + { + SimulateInstr1(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_XCHG) + { + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_op == OP_INC || _op == OP_DEC) + { + //Save address + _sAdr = _curAdr; + _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); + if (_endAdr) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + if (_item.Value != "") + Env->AddToBody("case " + _item.Value + " of"); + else + Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); + _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); + Env->AddToBody("end"); + //_curAdr = _endAdr; + _curPos = Adr2Pos(_curAdr); + continue; + } + //simulate dec as sub + DisInfo.OpNum = 2; + DisInfo.OpType[1] = otIMM; + DisInfo.Immediate = 1; + _cmpRes = GetCmpInfo(_curAdr + _instrLen); + if (_op == OP_DEC) + SimulateInstr2(_curAdr, OP_SUB); + else + SimulateInstr2(_curAdr, OP_ADD); + _curPos += _instrLen; _curAdr += _instrLen; + + if (_cmpRes == CMP_FAILED) continue; + + if (flags & CF_BJL) + { + CMPITEM* _cmpItem = new CMPITEM; + _cmpItem->L = CmpInfo.L; + _cmpItem->O = CmpInfo.O; + _cmpItem->R = CmpInfo.R; + Env->CmpStack->Add((void*)_cmpItem); + //skip jcc + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + + if (_cmpRes == CMP_BRANCH) + { + _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); + //Skip conditional branch + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); + _curAdr += _instrLen; + + _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo, DisInfo.Float); + _curPos = Adr2Pos(_curAdr); + continue; + } + if (_cmpRes == CMP_SET) + { + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); + SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + continue; + } + if (_op == OP_DIV || _op == OP_IDIV) + { + if (DisInfo.OpNum == 2) + { + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + } + if (_op == OP_MUL || _op == OP_IMUL) + { + _bytesToSkip = IsIntOver(_curAdr + _instrLen); + + if (DisInfo.OpNum == 1) + { + SimulateInstr1(_curAdr, _op); + _curPos += _instrLen + _bytesToSkip; _curAdr += _instrLen + _bytesToSkip; + continue; + } + if (DisInfo.OpNum == 2) + { + SimulateInstr2(_curAdr, _op); + _curPos += _instrLen + _bytesToSkip; _curAdr += _instrLen + _bytesToSkip; + continue; + } + if (DisInfo.OpNum == 3) + { + SimulateInstr3(_curAdr, _op); + _curPos += _instrLen + _bytesToSkip; _curAdr += _instrLen + _bytesToSkip; + continue; + } + } + if (_op == OP_CDQ) + { + _curPos += _instrLen; _curAdr += _instrLen; + GetRegItem(16, &_item); + _bytesToSkip = IsAbs(_curAdr); + if (_bytesToSkip) + { + _item.Flags = IF_CALL_RESULT; + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "Abs(" + _item.Value + ")"; + _item.Type = "Integer"; + SetRegItem(16, &_item); + + _line = "EAX := Abs(EAX)"; + _comment = _item.Value; + Env->AddToBody(_line + ";//" + _comment); + + _curPos += _bytesToSkip; _curAdr += _bytesToSkip; + } + SetRegItem(18, &_item);//Set edx to eax + continue; + } + if (_op == OP_MOVS) + { + GetRegItem(23, &_item1);//edi + GetRegItem(22, &_item2);//esi + //->lvar + if (_item1.Flags & IF_STACK_PTR) + { + if (_item1.Type != "") + _typeName = _item1.Type; + else + _typeName = _item2.Type; + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikRecord) + { + _size = GetRecordSize(_typeName); + for (int r = 0; r < _size; r++) + { + if (_item1.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = _curAdr; + throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); + } + _item = Env->Stack[_item1.IntValue + r]; + _item.Flags = IF_FIELD; + _item.Offset = r; + _item.Type = ""; + if (r == 0) _item.Type = _typeName; + Env->Stack[_item1.IntValue + r] = _item; + } + } + else if (_kind == ikArray) + { + _size = GetArraySize(_typeName); + _elSize = GetArrayElementTypeSize(_typeName); + _typeName = GetArrayElementType(_typeName); + if (!_size || !_elSize) + { + Env->ErrAdr = _curAdr; + throw Exception("Possibly incorrect array definition"); + } + for (int r = 0; r < _size; r += _elSize) + { + if (_item1.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = _curAdr; + throw Exception("Possibly incorrect array definition"); + } + Env->Stack[_item1.IntValue + r].Type = _typeName; + } + } + Env->AddToBody(Env->GetLvarName(_item1.IntValue, _typeName) + " := " + _item2.Value + ";"); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + //lvar-> + if (_item2.Flags & IF_STACK_PTR) + { + if (_item2.Type != "") + _typeName = _item2.Type; + else + _typeName = _item1.Type; + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikRecord) + { + _size = GetRecordSize(_typeName); + for (int r = 0; r < _size; r++) + { + if (_item2.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = _curAdr; + throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); + } + _item = Env->Stack[_item2.IntValue + r]; + _item.Flags = IF_FIELD; + _item.Offset = r; + _item.Type = ""; + if (r == 0) _item.Type = _typeName; + Env->Stack[_item2.IntValue + r] = _item; + } + } + else if (_kind == ikArray) + { + _size = GetArraySize(_typeName); + _elSize = GetArrayElementTypeSize(_typeName); + _typeName = GetArrayElementType(_typeName); + if (!_size || !_elSize) + { + Env->ErrAdr = _curAdr; + throw Exception("Possibly incorrect array definition"); + } + for (int r = 0; r < _size; r += _elSize) + { + if (_item1.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = _curAdr; + throw Exception("Possibly incorrect array definition"); + } + Env->Stack[_item1.IntValue + r].Type = _typeName; + } + } + Env->AddToBody(_item1.Value + " := " + Env->GetLvarName(_item2.IntValue, _typeName) + ";"); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (_item1.Value != "") + _line = _item1.Value; + else + _line = "_edi_"; + _line += " := "; + if (_item2.Value != "") + _line += _item2.Value; + else + _line += "_esi_"; + _line += ";"; + Env->AddToBody(_line); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + if (DisInfo.Float) + { + SimulateFloatInstruction(_curAdr); + _curPos += _instrLen; _curAdr += _instrLen; + continue; + } + + Env->ErrAdr = _curAdr; + throw Exception("Still unknown"); + } + return _curAdr; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateInherited(DWORD procAdr) +{ + PInfoRec _recN = GetInfoRec(procAdr); + _ESP_ += _recN->procInfo->retBytes; +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompiler::SimulateCall(DWORD curAdr, DWORD callAdr, int instrLen, PMethodRec recM, DWORD AClassAdr) +{ + bool _sep, _fromKB, _vmt; + BYTE _kind, _callKind, _retKind, _methodKind, *p, *pp; + int _res = 0; + int _argsNum, _retBytes, _retBytesCalc, _len, _val, _esp; + int _idx = -1, _rn, _ndx, ss, _pos, _size, _recsize; + WORD* _uses; + DWORD _classAdr, _adr, _dynAdr; + char *tmpBuf; + ITEM _item, _item1; + ARGINFO _aInfo, *_argInfo = &_aInfo; + PFIELDINFO _fInfo; + MProcInfo _pInfo; + PMethodRec _recM; + PInfoRec _recN, _recN1; + MTypeInfo _tInfo; + TDecompiler *de; + String _name, _type, _alias, _line, _retType, _value, _iname, _embAdr; + String _typeName, _comment, _regName, _propName, _lvarName; + + pp = 0; ss = 0; _propName = ""; + //call imm + if (IsValidCodeAdr(callAdr)) + { + _recN = GetInfoRec(callAdr); + _name = _recN->GetName(); + //Is it property function (Set, Get, Stored)? + if (_name.Pos(".")) + { + _propName = KnowledgeBase.IsPropFunction(ExtractClassName(_name), ExtractProcName(_name)); + } + if (SameText(_name, "@AbstractError")) + { + Env->ErrAdr = curAdr; + throw Exception("Pure Virtual Call"); + } + //Import can have no prototype + if (IsFlagSet(cfImport, Adr2Pos(callAdr))) + { + if (!CheckPrototype(_recN)) + { + Env->AddToBody(_recN->GetName() + "(...);//Import"); + _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%lX", &_retBytes); + _ESP_ += _retBytes; + return false; + } + } + //@DispInvoke + if (SameText(_name, "@DispInvoke")) + { + Env->AddToBody("DispInvoke(...);"); + _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%lX", &_retBytes); + _ESP_ += _retBytes; + return false; + } + if (!recM) + { + _name = _recN->GetName(); + _callKind = _recN->procInfo->flags & 7; + _methodKind = _recN->kind; + _argsNum = (_recN->procInfo->args) ? _recN->procInfo->args->Count : 0; + _retType = _recN->type; + _fromKB = (_recN->kbIdx != -1); + _retBytes = _recN->procInfo->retBytes; + //stdcall, pascal, cdecl - return bytes = 4 * ArgsNum + if ((_callKind == 3 || _callKind == 2 || _callKind == 1) && !_retBytes) + _retBytes = _argsNum * 4; + if (_recN->procInfo->flags & PF_EMBED) + { + _embAdr = Val2Str8(callAdr); + if (Env->EmbeddedList->IndexOf(_embAdr) == -1) + { + Env->EmbeddedList->Add(_embAdr); + int _savedIdx = FMain_11011981->lbCode->ItemIndex; + FMain_11011981->lbCode->ItemIndex = -1; + if (Application->MessageBox(String("Decompile embedded procedure at address " + _embAdr + "?").c_str(), "Confirmation", MB_YESNO) == IDYES) + { + Env->AddToBody("//BEGIN_EMBEDDED_" + _embAdr); + Env->AddToBody(_recN->MakePrototype(callAdr, true, false, false, true, false)); + DWORD _savedStartAdr = Env->StartAdr; + bool _savedBpBased = Env->BpBased; + int _savedLocBase = Env->LocBase; + int _savedSize = Env->Size; + Env->StartAdr = callAdr; + _size = GetProcSize(callAdr); + Env->Size = _size; + de = new TDecompiler(Env); + _ESP_ -= 4;//ret address + de->SetStackPointers(this); + de->SetStop(callAdr + _size); + try + { + Env->AddToBody("begin"); + de->Decompile(callAdr, 0, 0); + Env->AddToBody("end"); + Env->AddToBody("//END_EMBEDDED_" + _embAdr); + } + catch(Exception &exception) + { + delete de; + throw Exception("Embedded->" + exception.Message); + } + _ESP_ += 4; + delete de; + Env->StartAdr = _savedStartAdr; + Env->Size = _savedSize; + Env->BpBased = _savedBpBased; + Env->LocBase = _savedLocBase; + } + FMain_11011981->lbCode->ItemIndex = _savedIdx; + } + } + } + else + { + _name = recM->name; + _res = (int)KnowledgeBase.GetProcInfo(recM->name.c_str(), INFO_DUMP | INFO_ARGS, &_pInfo, &_idx); + if (_res && _res != -1) + { + _callKind = _pInfo.CallKind; + switch (_pInfo.MethodKind) + { + case 'C': + _methodKind = ikConstructor; + break; + case 'D': + _methodKind = ikDestructor; + break; + case 'F': + _methodKind = ikFunc; + break; + case 'P': + _methodKind = ikProc; + break; + } + _argsNum = (_pInfo.Args) ? _pInfo.ArgsNum : 0; + _retType = _pInfo.TypeDef; + pp = _pInfo.Args; + _fromKB = true; + _retBytes = GetProcRetBytes(&_pInfo); + } + else + { + _name = _recN->GetName(); + _callKind = _recN->procInfo->flags & 7; + _methodKind = _recN->kind; + _argsNum = (_recN->procInfo->args) ? _recN->procInfo->args->Count : 0; + _retType = _recN->type; + _fromKB = false; + _retBytes = _recN->procInfo->retBytes; + } + } + //Check prototype + if (!_fromKB) + { + if (!CheckPrototype(_recN)) + { + Env->ErrAdr = curAdr; + if (_name != "") + throw Exception("Prototype of " + _name + " is not completed"); + else + throw Exception("Prototype of " + GetDefaultProcName(callAdr) + " is not completed"); + } + } + if (_name != "") + { + if (_name[1] == '@') + { + if (SameText(_name, "@CallDynaInst") || + SameText(_name, "@CallDynaClass")) + { + _recN = GetInfoRec(curAdr); + if (_recN) + { + PICODE* _picode = _recN->picode; + if (_picode && _picode->Op == OP_CALL) + { + SimulateCall(curAdr, _picode->Ofs.Address, instrLen, 0, 0); + return false; + } + } + else + { + GetRegItem(16, &_item); + if (DelphiVersion <= 5) + { + GetRegItem(11, &_item1); + _comment = GetDynaInfo(GetClassAdr(_item.Type), _item1.IntValue, &_dynAdr); //bx + } + else + { + GetRegItem(14, &_item1); + _comment = GetDynaInfo(GetClassAdr(_item.Type), _item1.IntValue, &_dynAdr); //si + } + AddPicode(Adr2Pos(curAdr), OP_CALL, _comment, _dynAdr); + SimulateCall(curAdr, _dynAdr, instrLen, 0, 0); + return false; + } + } + _alias = GetSysCallAlias(_name); + if (_alias == "") + { + return SimulateSysCall(_name, curAdr, instrLen); + } + _name = _alias; + } + //Some special functions + if (SameText(_name, "Format")) + { + SimulateFormatCall(); + return false; + } + if (_name.Pos(".")) + { + _line = ExtractProcName(_name); + } + else + _line = _name; + } + else + _line = GetDefaultProcName(callAdr); + + if (_propName != "") + _line += "{" + _propName + "}"; + + if (_methodKind == ikFunc) + { + if (SameText(_name, "TList.Get")) + { + while (1) + { + _retType = ManualInput(Env->StartAdr, curAdr, "Define type of function at " + IntToHex((int)curAdr, 8), "Type:"); + if (_retType == "") + { + Env->ErrAdr = curAdr; + throw Exception("You need to define type of function later"); + } + //if (_retType[1] == '^') + // _retType = GetTypeDeref(_retType); + _retKind = GetTypeKind(_retType, &_size); + if (_retKind) break; + } + } + else + { + while (1) + { + if (_retType[1] == '^') + _retType = GetTypeDeref(_retType); + + _retKind = GetTypeKind(_retType, &_size); + if (_retKind) break; + + _retType = ManualInput(Env->StartAdr, curAdr, "Define type of function at " + IntToHex((int)curAdr, 8), "Type:"); + if (_retType == "") + { + Env->ErrAdr = curAdr; + throw Exception("You need to define type of function later"); + } + } + } + } + + _retBytesCalc = 0; _ndx = 0; + if (_argsNum) + { + _line += "("; + if (_callKind == 0 || _callKind == 3 || _callKind == 2 || _callKind == 1)//fastcall, stdcall, pascal, cdecl + { + _sep = false; _esp = _ESP_; + _ESP_ += _retBytes; + //fastcall, pascal - reverse order of arguments + if (_callKind == 0 || _callKind == 2) _esp = _ESP_; + //cdecl - stack restored by caller + if (_callKind == 1) _ESP_ -= _retBytes; + + for (int n = 0; n < _argsNum; n++) + { + if (pp) + FillArgInfo(n, _callKind, _argInfo, &pp, &ss); + else + _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; + + _rn = -1; _regName = ""; + _kind = GetTypeKind(_argInfo->TypeDef, &_size); + if (_kind == ikFloat || _kind == ikInt64) + _size = _argInfo->Size; + else + _size = 4; + if (_argInfo->Tag == 0x22) _size = 4; + + if (_callKind == 0)//fastcall + { + if (_methodKind == ikConstructor) + { + if (_ndx <= 1) + { + if (!_ndx) + { + GetRegItem(16, &_item); + _retType = _item.Type; + _retKind = GetTypeKind(_retType, &_size); + _line = _retType + ".Create("; + } + _ndx++; + continue; + } + } + if ((_kind == ikFloat || _kind == ikInt64) && _argInfo->Tag != 0x22) + { + _esp -= _size; + _item = Env->Stack[_esp]; + _item1 = Env->Stack[_esp + 4]; + _retBytesCalc += _size; + } + else + { + //fastcall + if (_ndx >= 0 && _ndx <= 2) + { + //eax + if (_ndx == 0) + { + _rn = 16; + _regName = "EAX"; + } + //edx + else if (_ndx == 1) + { + _rn = 18; + _regName = "EDX"; + } + //ecx + else + { + _rn = 17; + _regName = "ECX"; + } + GetRegItem(_rn, &_item); + _ndx++; + } + //stack args + else + { + _esp -= _argInfo->Size; + _item = Env->Stack[_esp]; + _retBytesCalc += _argInfo->Size; + } + } + } + else if (_callKind == 3 || _callKind == 1)//stdcall, cdecl + { + if (_size >= 8) + { + _item = Env->Stack[_esp]; + _item1 = Env->Stack[_esp + 4]; + _esp += _size; + _retBytesCalc += _size; + } + else + { + _item = Env->Stack[_esp]; + _esp += _argInfo->Size; + _retBytesCalc += _argInfo->Size; + } + } + if (SameText(_argInfo->Name, "Self")) + { + if (!SameText(_item.Value, "Self")) _line = _item.Value + "." + _line; + _sep = false; + continue; + } + if (SameText(_argInfo->Name, "_Dv__")) + { + _sep = false; + continue; + } + if (_sep) _line += ", "; _sep = true; + if (_item.Flags & IF_STACK_PTR) + { + _item1 = Env->Stack[_item.IntValue]; + if (_kind == ikInteger) + { + _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); + _line += _lvarName; + Env->Stack[_item.IntValue].Value = _lvarName; + continue; + } + if (_kind == ikEnumeration) + { + _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); + _line += _lvarName; + Env->Stack[_item.IntValue].Value = _lvarName; + continue; + } + if (_kind == ikLString || _kind == ikVariant) + { + _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); + _line += _lvarName; + Env->Stack[_item.IntValue].Value = _lvarName;; + Env->Stack[_item.IntValue].Type = _argInfo->TypeDef; + continue; + } + if (_kind == ikVMT || _kind == ikClass) + { + _line += _item1.Value; + continue; + } + if (_kind == ikArray) + { + _line += Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); + continue; + } + if (_kind == ikRecord) + { + _line += Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); + _recsize = GetRecordSize(_argInfo->TypeDef); + for (int r = 0; r < _recsize; r++) + { + if (_item.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = curAdr; + throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); + } + _item1 = Env->Stack[_item.IntValue + r]; + _item1.Flags = IF_FIELD; + _item1.Offset = r; + _item1.Type = ""; + if (r == 0) _item1.Type = _argInfo->TypeDef; + Env->Stack[_item.IntValue + r] = _item1; + } + continue; + } + //Type not found + _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); + _line += _lvarName; + Env->Stack[_item.IntValue].Value = _lvarName; + Env->Stack[_item.IntValue].Type = _argInfo->TypeDef; + continue; + } + if (_kind == ikInteger) + { + _line += _item.Value; + if (_item.Flags & IF_INTVAL) _line += "{" + GetImmString(_item.IntValue) + "}"; + continue; + } + if (_kind == ikChar) + { + _line += _item.Value; + if (_item.Flags & IF_INTVAL) _line += "{'" + String(_item.IntValue) + "'}"; + continue; + } + if (_kind == ikLString || _kind == ikWString || _kind == ikUString || _kind == ikCString || _kind == ikWCString) + { + if (_item.Value != "") + _line += _item.Value; + else + { + if (_item.Flags & IF_INTVAL) + { + if (!_item.IntValue) + _line += "''"; + else + { + _recN1 = GetInfoRec(_item.IntValue); + if (_recN1) + _line += _recN1->GetName(); + else + { + if (_kind == ikCString) + { + _line += "'" + String((char*)(Code + Adr2Pos(_item.IntValue))) + "'"; + } + else if (_kind == ikLString) + _line += TransformString(Code + Adr2Pos(_item.IntValue), -1); + else + _line += TransformUString(CP_ACP, (wchar_t*)(Code + Adr2Pos(_item.IntValue)), -1); + } + } + } + } + continue; + } + if (_kind == ikVMT || _kind == ikClass) + { + if (_item.Value != "") + _line += _item.Value; + else + { + if ((_item.Flags & IF_INTVAL) && (!_item.IntValue)) + _line += "Nil"; + else + _line += "?"; + } + continue; + } + if (_kind == ikEnumeration) + { + if (_rn != -1) _line += _regName + "{"; + if (_item.Flags & IF_INTVAL) + { + _line += GetEnumerationString(_argInfo->TypeDef, _item.IntValue); + } + else if (_item.Value != "") + { + _line += _item.Value; + } + if (_rn != -1) _line += "}"; + continue; + } + if (_kind == ikSet) + { + if (_item.Flags & IF_INTVAL) + { + if (IsValidImageAdr(_item.IntValue)) + _line += GetSetString(_argInfo->TypeDef, Code + Adr2Pos(_item.IntValue)); + else + _line += GetSetString(_argInfo->TypeDef, (BYTE*)&_item.IntValue); + } + else + _line += _item.Value; + continue; + } + if (_kind == ikRecord) + { + if (_size < 8) + _line += _item.Value; + else + _line += _item1.Value; + continue; + } + if (_kind == ikFloat) + { + if (_item.Flags & IF_INTVAL) + { + GetFloatItemFromStack(_esp, &_item, FloatNameToFloatType(_argInfo->TypeDef)); + } + _line += _item.Value; + continue; + } + if (_kind == ikInt64) + { + if (_item.Flags & IF_INTVAL) + { + GetInt64ItemFromStack(_esp, &_item); + } + _line += _item.Value; + continue; + } + if (_kind == ikClassRef) + { + _line += _item.Type; + continue; + } + if (_kind == ikResString) + { + _line += _item.Value; + continue; + } + if (_kind == ikPointer) + { + if ((_item.Flags & IF_INTVAL) && IsValidImageAdr(_item.IntValue)) + { + _recN1 = GetInfoRec(_item.IntValue); + if (_recN1 && _recN1->HasName()) + _line += _recN1->GetName(); + else + _line += "sub_" + Val2Str8(_item.IntValue); + continue; + } + } + //var + if (_argInfo->Tag == 0x22) + { + _adr = _item.IntValue; + if (IsValidImageAdr(_adr)) + { + _recN1 = GetInfoRec(_adr); + if (_recN1 && _recN1->HasName()) + _line += _recN1->GetName(); + else + _line += MakeGvarName(_adr); + } + else + _line += _item.Value; + continue; + } + if (_argInfo->Size == 8) + { + if (SameText(_item1.Value, "Self")) + { + if ((_item.Flags & IF_INTVAL) && IsValidImageAdr(_item.IntValue)) + { + _recN1 = GetInfoRec(_item.IntValue); + if (_recN1 && _recN1->HasName()) + _line += _recN1->GetName(); + else + _line += "sub_" + Val2Str8(_item.IntValue); + continue; + } + } + _line += _item.Value; + continue; + } + if (_item.Value != "") + _line += _item.Value; + else if (_item.Flags & IF_INTVAL) + _line += String(_item.IntValue); + else + _line += "?"; + continue; + } + } + _len = _line.Length(); + if (_line[_len] != '(') + _line += ")"; + else + _line.SetLength(_len - 1); + } + if (_methodKind != ikFunc && _methodKind != ikConstructor) + { + _line += ";"; + if (Env->LastResString != "") + { + _line += "//" + QuotedStr(Env->LastResString); + Env->LastResString = ""; + } + Env->AddToBody(_line); + } + else + { + if (_callKind == 0)//fastcall + { + if (_retKind == ikLString || + _retKind == ikUString || + _retKind == ikRecord || + _retKind == ikVariant || + _retKind == ikArray) + { + //eax + if (_ndx == 0) + GetRegItem(16, &_item); + //edx + else if (_ndx == 1) + GetRegItem(18, &_item); + //ecx + else if (_ndx == 2) + GetRegItem(17, &_item); + //last pushed + else + { + _esp -= 4; + _item = Env->Stack[_esp]; + } + + if (_item.Flags & IF_STACK_PTR) + { + if (_item.Name != "") + _line = _item.Name + " := " + _line; + else if (_item.Value != "") + _line = _item.Value + " := " + _line; + else + _line = Env->GetLvarName(_item.IntValue, _retType) + " := " + _line; + if (_retKind == ikRecord) + { + /* + _size = GetRecordSize(_retType); + for (int r = 0; r < _size; r++) + { + if (_item.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = curAdr; + throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); + } + _item1 = Env->Stack[_item.IntValue + r]; + _item1.Flags = IF_FIELD; + _item1.Offset = r; + _item1.Type = ""; + if (r == 0) _item1.Type = _retType; + Env->Stack[_item.IntValue + r] = _item1; + } + */ + } + Env->Stack[_item.IntValue].Flags = 0; + Env->Stack[_item.IntValue].Type = _retType; + } + else + _line = _item.Value + " := " + _line; + + _line += ";"; + if (Env->LastResString != "") + { + _line += "//" + QuotedStr(Env->LastResString); + Env->LastResString = ""; + } + Env->AddToBody(_line); + } + else if (_retKind == ikFloat) + { + InitItem(&_item); + _item.Value = _line; + _item.Type = _retType; + FPush(&_item); + } + else + { + //???__int64 + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Flags = IF_CALL_RESULT; + _item.Value = _line; + _item.Type = _retType; + SetRegItem(16, &_item); + _line += ";"; + if (Env->LastResString != "") + { + _line += "//" + QuotedStr(Env->LastResString); + Env->LastResString = ""; + } + Env->AddToBody("EAX := " + _line); + } + } + else if (_callKind == 3 || _callKind == 1)//stdcall, cdecl + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Flags = IF_CALL_RESULT; + _item.Value = _line; + _item.Type = _retType; + SetRegItem(16, &_item); + _line += ";"; + Env->AddToBody("EAX := " + _line); + } + } + if (_callKind == 3 && _retBytesCalc != _retBytes) + { + Env->ErrAdr = curAdr; + throw Exception("Incorrect number of return bytes!"); + } + //_ESP_ += _retBytes; + return false; + } + //call [reg+N] + if (DisInfo.BaseReg != -1) + { + //esp + if (DisInfo.BaseReg == 20) + { + _item = Env->Stack[_ESP_ + DisInfo.Offset]; + _line = Env->GetLvarName(_ESP_ + DisInfo.Offset, "") + "(...);"; + Env->AddToBody(_line); + _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%lX", &_retBytes); + _ESP_ += _retBytes; + return false; + } + + GetRegItem(DisInfo.BaseReg, &_item); + _classAdr = 0; + //if (SameText(_item.Value, "Self")) + //{ + // Env->ErrAdr = curAdr; + // throw Exception("Under construction"); + //} + if (_item.Type != "") + _classAdr = GetClassAdr(_item.Type); + if (_item.Flags & IF_VMT_ADR) + _classAdr = _item.IntValue; + if (IsValidImageAdr(_classAdr)) + { + //Interface + if (_item.Flags & IF_INTERFACE) + { + Env->AddToBody(_item.Value + ".I" + String(DisInfo.Offset) + "(...);"); + _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%lX", &_retBytes); + _ESP_ += _retBytes; + return false; + } + //Method + _recM = FMain_11011981->GetMethodInfo(_classAdr, 'V', DisInfo.Offset); + if (_recM) + { + callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - cVmtSelfPtr + DisInfo.Offset)); + if (_recM->abstract) + { + _classAdr = GetChildAdr(_classAdr); + callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - cVmtSelfPtr + DisInfo.Offset)); + } + if (_recM->name != "") + return SimulateCall(curAdr, callAdr, instrLen, _recM, _classAdr); + else + return SimulateCall(curAdr, callAdr, instrLen, 0, _classAdr); + } + //Field + if (GetField(_item.Type, DisInfo.Offset, _name, _type) < 0) + { + while (!_recM) + { + _typeName = ManualInput(CurProcAdr, curAdr, "Class (" + _item.Type + ") has no such virtual method. Give correct class name", "Name:"); + if (_typeName == "") + { + Env->ErrAdr = curAdr; + throw Exception("Possibly incorrect class (has no such virtual method)"); + } + _classAdr = GetClassAdr(_typeName); + _recM = FMain_11011981->GetMethodInfo(_classAdr, 'V', DisInfo.Offset); + } + callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - cVmtSelfPtr + DisInfo.Offset)); + if (_recM->abstract) + { + _classAdr = GetChildAdr(_classAdr); + callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - cVmtSelfPtr + DisInfo.Offset)); + } + if (_recM->name != "") + return SimulateCall(curAdr, callAdr, instrLen, _recM, _classAdr); + else + return SimulateCall(curAdr, callAdr, instrLen, 0, _classAdr); + } + else + { + if (_name != "") + Env->AddToBody(_name + "(...);"); + else + Env->AddToBody("f" + Val2Str0(DisInfo.Offset) + "(...);"); + _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%lX", &_retBytes); + _ESP_ += _retBytes; + return false; + } + } + if (_item.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_item.IntValue + DisInfo.Offset]; + _line = _item.Value + ";"; + Env->AddToBody(_line); + _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%lX", &_retBytes); + _ESP_ += _retBytes; + return false; + } + } + //call reg + if (DisInfo.OpNum == 1 && DisInfo.OpType[0] == otREG) + { + //GetRegItem(DisInfo.OpRegIdx[0], &_item); + //_line = _item.Value + ";"; + Env->AddToBody("call...;"); + _value = ManualInput(CurProcAdr, curAdr, "Input stack arguments number of procedure at " + Val2Str8(curAdr), "ArgsNum:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%d", &_argsNum); + _ESP_ += _argsNum * 4; + return false; + } + //call [reg+N] + if (DisInfo.OpNum == 1 && DisInfo.OpType[0] == otMEM) + { + Env->AddToBody("call("); + _value = ManualInput(CurProcAdr, curAdr, "Input stack arguments number of procedure at " + Val2Str8(curAdr), "ArgsNum:"); + if (_value == "") + { + Env->ErrAdr = curAdr; + throw Exception("Bye!"); + } + sscanf(_value.c_str(), "%d", &_argsNum); + + while (_argsNum) + { + _item = Env->Stack[_ESP_]; + if (_item.Flags & IF_INTVAL) + Env->AddToBody(String(_item.IntValue)); + else + Env->AddToBody(_item.Value); + _ESP_ += 4; + _argsNum--; + } + Env->AddToBody(");"); + return false; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +int __fastcall TDecompiler::GetCmpInfo(DWORD fromAdr) +{ + BYTE _b, _op; + int _curPos; + DWORD _curAdr = fromAdr; + DISINFO _disInfo; + + _curPos = Adr2Pos(_curAdr); + CmpAdr = 0; + + Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + if (_disInfo.Conditional && IsValidCodeAdr(_disInfo.Immediate)) + { + _b = *(Code + _curPos); + if (_b == 0xF) _b = *(Code + _curPos + 1); + _b = (_b & 0xF) + 'A'; + if (_b == 'A' || _b == 'B') return CMP_FAILED; + CmpAdr = _disInfo.Immediate; + CmpOp = _b; + return CMP_BRANCH; + } + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_SET) + { + CmpAdr = 0; + _b = *(Code + _curPos + 1); + CmpOp = (_b & 0xF) + 'A'; + return CMP_SET; + } + return CMP_FAILED; +} +//--------------------------------------------------------------------------- +//"for" cycle types +//1 - for I := C1 to C2 +//2 - for I := 0 to N +//3 - for I := 1 to N +//4 - for I := C to N +//5 - for I := N to C +//6 - for I ;= N1 to N2 +//7 - for I := C1 downto C2 +//8 - for I := 0 downto N +//9 - for I := C downto N +//10 - for I := N downto C +//11 - for I := N1 downto N2 +PLoopInfo __fastcall TDecompiler::GetLoopInfo(int fromAdr) +{ + bool noVar = true; + bool down = false; + bool bWhile = false; + BYTE _op; + int instrLen, pos, pos1, fromPos, num, intTo, idx, idxVal; + DWORD maxAdr, brkAdr, lastAdr, stopAdr, _dd, _dd1; + PInfoRec recN; + PLoopInfo res; + DISINFO _disInfo; + String from, to, cnt; + ITEM item; + IDXINFO varIdxInfo, cntIdxInfo; + + fromPos = Adr2Pos(fromAdr); + pos1 = GetNearestUpInstruction(fromPos); + Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'pmj') bWhile = true; + + recN = GetInfoRec(fromAdr); + if (recN && recN->xrefs) + { + maxAdr = 0; + for (int n = 0; n < recN->xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; + if (recX->adr + recX->offset > maxAdr) maxAdr = recX->adr + recX->offset; + } + //Instruction at maxAdr + instrLen = Disasm.Disassemble(Code + Adr2Pos(maxAdr), (__int64)maxAdr, &_disInfo, 0); + brkAdr = maxAdr + instrLen; + lastAdr = maxAdr; + if (bWhile) + { + res = new TLoopInfo('W', fromAdr, brkAdr, lastAdr);//while + return res; + } + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'pmj') + { + res = new TLoopInfo('T', fromAdr, brkAdr, lastAdr);//while true + res->whileInfo = new TWhileInfo(true); + return res; + } + //First instruction before maxAdr + pos1 = GetNearestUpInstruction(Adr2Pos(maxAdr), fromPos); + Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &_disInfo, 0); + _dd1 = *((DWORD*)_disInfo.Mnem); + //cmp reg/mem, imm + if (_dd1 == 'pmc' && _disInfo.OpType[1] == otIMM) + { + noVar = false; + GetCycleIdx(&varIdxInfo, &_disInfo); + intTo = _disInfo.Immediate; + //Find mov reg/mem,... + pos = fromPos; + while (1) + { + pos = GetNearestUpInstruction(pos); + instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + if (_disInfo.Branch || IsFlagSet(cfProcStart, pos)) + { + res = new TLoopInfo('R', fromAdr, brkAdr, lastAdr);//repeat + return res; + } + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_MOV || _op == OP_XOR) + { + if (varIdxInfo.IdxType == itREG && _disInfo.OpType[0] == otREG && IsSameRegister(_disInfo.OpRegIdx[0], varIdxInfo.IdxValue)) + { + GetRegItem(varIdxInfo.IdxValue, &item); + if (item.Flags & IF_INTVAL) + { + from = String(item.IntValue); + item.Flags &= ~IF_INTVAL; + } + else + from = item.Value; + item.Value = GetDecompilerRegisterName(varIdxInfo.IdxValue); + SetRegItem(varIdxInfo.IdxValue, &item); + break; + } + if (varIdxInfo.IdxType == itLVAR && _disInfo.OpType[0] == otMEM) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + if (item.IntValue + _disInfo.Offset == varIdxInfo.IdxValue) + { + if (Env->Stack[varIdxInfo.IdxValue].Flags & IF_INTVAL) + from = String(Env->Stack[varIdxInfo.IdxValue].IntValue); + else + from = Env->Stack[varIdxInfo.IdxValue].Value; + Env->Stack[varIdxInfo.IdxValue].Value = Env->GetLvarName(varIdxInfo.IdxValue, "Integer"); + break; + } + } + if (_disInfo.BaseReg == 20)//[esp+N] + { + if (_ESP_ + _disInfo.Offset == varIdxInfo.IdxValue) + { + if (Env->Stack[varIdxInfo.IdxValue].Flags & IF_INTVAL) + from = String(Env->Stack[varIdxInfo.IdxValue].IntValue); + else + from = Env->Stack[varIdxInfo.IdxValue].Value; + Env->Stack[varIdxInfo.IdxValue].Value = Env->GetLvarName(varIdxInfo.IdxValue, "Integer"); + break; + } + } + } + } + } + //Find array elements + pos += instrLen; + while (1) + { + if (pos == fromPos) break; + + instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //lea reg, mem + if (_op == OP_LEA && _disInfo.OpType[1] == otMEM) + { + idx = _disInfo.OpRegIdx[0]; + GetRegItem(idx, &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(idx, &item); + pos += instrLen; + continue; + } + //mov reg, esp + if (_op == OP_MOV && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[1] == 20) + { + idx = _disInfo.OpRegIdx[0]; + GetRegItem(idx, &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(idx, &item); + pos += instrLen; + continue; + } + //mov + if (_op == OP_MOV) + { + if (_disInfo.OpType[1] == otIMM && IsValidImageAdr(_disInfo.Immediate)) + { + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(_disInfo.OpRegIdx[0], &item); + } + if (_disInfo.OpType[0] == otMEM) + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; + } + } + } + if (_disInfo.OpType[1] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[1], &item); + if (item.Flags & IF_ARRAY_PTR) + { + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(_disInfo.OpRegIdx[0], &item); + } + if (_disInfo.OpType[0] == otMEM) + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; + } + } + } + } + if (_disInfo.OpType[1] == otMEM) + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + if (Env->Stack[idxVal].Flags & IF_ARRAY_PTR) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(_disInfo.OpRegIdx[0], &item); + } + } + } + } + pos += instrLen; + } + //4 + pos = Adr2Pos(maxAdr); stopAdr = brkAdr; + pos = GetNearestUpInstruction(pos); + while (1) + { + pos = GetNearestUpInstruction(pos); + Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'cni' || _dd == 'ced' || _dd == 'dda' || _dd == 'bus') + { + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + if (item.Flags & IF_ARRAY_PTR) + { + stopAdr = Pos2Adr(pos); + continue; + } + if (varIdxInfo.IdxType == itREG && IsSameRegister(_disInfo.OpRegIdx[0], varIdxInfo.IdxValue)) + { + if (_dd == 'ced') down = true; + stopAdr = Pos2Adr(pos); + } + break; + } + if (_disInfo.OpType[0] == otMEM) + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + if (Env->Stack[idxVal].Flags & IF_ARRAY_PTR) + { + stopAdr = Pos2Adr(pos); + continue; + } + if (varIdxInfo.IdxType == itLVAR && varIdxInfo.IdxValue == idxVal) + { + if (_dd == 'ced') down = true; + stopAdr = Pos2Adr(pos); + } + } + break; + } + } + break; + } + res = new TLoopInfo('F', fromAdr, brkAdr, lastAdr);//for + if (!down) + to = String(intTo - 1); + else + to = String(intTo + 1); + res->forInfo = new TForInfo(noVar, down, stopAdr, from, to, varIdxInfo.IdxType, varIdxInfo.IdxValue, -1, -1); + return res; + } + if (_dd1 == 'cni' || _dd1 == 'ced') + { + from = "1"; + //1 + GetCycleIdx(&cntIdxInfo, &_disInfo); + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + if (item.Flags & IF_INTVAL) + cnt = String(item.IntValue); + else if (item.Value1 != "") + cnt = item.Value1; + else + cnt = item.Value; + } + if (_disInfo.OpType[0] == otMEM) + { + GetRegItem(_disInfo.BaseReg, &item); + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + item = Env->Stack[item.IntValue + _disInfo.Offset]; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + item = Env->Stack[_ESP_ + _disInfo.Offset]; + } + if (item.Flags & IF_INTVAL) + cnt = String(item.IntValue); + else + cnt = item.Value; + } + } + //2 + pos = fromPos; + while (1) + { + pos = GetNearestUpInstruction(pos); + instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + if (SameText(cntIdxInfo.IdxStr, String(_disInfo.Op1))) + break; + } + //3 + pos += instrLen; + while (1) + { + if (pos == fromPos) break; + + instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //lea reg1, mem + if (_op == OP_LEA && _disInfo.OpType[1] == otMEM) + { + idx = _disInfo.OpRegIdx[0]; + GetRegItem(idx, &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(idx, &item); + pos += instrLen; + continue; + } + //mov reg, esp + if (_op == OP_MOV && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[1] == 20) + { + idx = _disInfo.OpRegIdx[0]; + GetRegItem(idx, &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(idx, &item); + pos += instrLen; + continue; + } + if (_op == OP_MOV) + { + if (_disInfo.OpType[1] == otIMM) + { + if (!IsValidImageAdr(_disInfo.Immediate)) + { + GetCycleIdx(&varIdxInfo, &_disInfo); + noVar = false; + } + else + { + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(_disInfo.OpRegIdx[0], &item); + } + else//otMEM + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; + } + } + } + } + if (_disInfo.OpType[1] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[1], &item); + int _size; + int _kind = GetTypeKind(item.Type, &_size); + if ((item.Flags & IF_ARRAY_PTR) || _kind == ikArray || _kind == ikDynArray) + { + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(_disInfo.OpRegIdx[0], &item); + } + else//otMEM + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; + } + } + } + else + { + GetCycleIdx(&varIdxInfo, &_disInfo); + noVar = false; + } + } + if (_disInfo.OpType[1] == otMEM) + { + //??????!!!!!! + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + item = Env->Stack[idxVal]; + if (item.Flags & IF_VAR) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + item.Flags |= IF_ARRAY_PTR; + SetRegItem(_disInfo.OpRegIdx[0], &item); + pos += instrLen; + continue; + } + if (!(item.Flags & IF_ARRAY_PTR)) + { + GetCycleIdx(&varIdxInfo, &_disInfo); + noVar = false; + } + } + } + } + pos += instrLen; + } + //4 + pos = GetNearestUpInstruction(Adr2Pos(maxAdr)); stopAdr = Pos2Adr(pos); + while (1) + { + pos = GetNearestUpInstruction(pos); + Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'cni' || _dd == 'ced' || _dd == 'dda' || _dd == 'bus') + { + if (_disInfo.OpType[0] == otREG) + { + GetRegItem(_disInfo.OpRegIdx[0], &item); + if (item.Flags & IF_ARRAY_PTR) + { + stopAdr = Pos2Adr(pos); + continue; + } + if (noVar) + { + GetCycleIdx(&varIdxInfo, &_disInfo); + if (item.Flags & IF_INTVAL) + { + from = String(item.IntValue); + item.Flags &= ~IF_INTVAL; + } + else + from = item.Value; + stopAdr = Pos2Adr(pos); + } + else + { + if (varIdxInfo.IdxType == itREG && IsSameRegister(_disInfo.OpRegIdx[0], varIdxInfo.IdxValue)) + { + if (_dd == 'ced') down = true; + stopAdr = Pos2Adr(pos); + } + } + break; + } + if (_disInfo.OpType[0] == otMEM) + { + if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) + { + if (_disInfo.BaseReg == 21)//[ebp-N] + { + GetRegItem(_disInfo.BaseReg, &item); + idxVal = item.IntValue + _disInfo.Offset; + } + if (_disInfo.BaseReg == 20)//[esp-N] + { + idxVal = _ESP_ + _disInfo.Offset; + } + item = Env->Stack[idxVal]; + if (item.Flags & IF_ARRAY_PTR) + { + stopAdr = Pos2Adr(pos); + continue; + } + if (!noVar && varIdxInfo.IdxType == itLVAR && varIdxInfo.IdxValue == idxVal) + { + if (_dd == 'ced') down = true; + stopAdr = Pos2Adr(pos); + } + break; + } + } + } + break; + } + //from, to + if (noVar) + { + //from = "1"; + if (cntIdxInfo.IdxType == itREG) + { + if (SameText(from, "1")) + to = cnt; + else + to = cnt + " + " + from + " - 1"; + GetRegItem(cntIdxInfo.IdxValue, &item); + if (item.Flags & IF_INTVAL) + { + //to = String(item.IntValue); + item.Flags &= ~IF_INTVAL; + } + //else + // to = item.Value; + item.Value = GetDecompilerRegisterName(cntIdxInfo.IdxValue); + SetRegItem(cntIdxInfo.IdxValue, &item); + } + else if (cntIdxInfo.IdxType == itLVAR) + { + item = Env->Stack[cntIdxInfo.IdxValue]; + if (item.Flags & IF_INTVAL) + { + //to = String(item.IntValue); + item.Flags &= ~IF_INTVAL; + } + //else + // to = item.Value; + item.Value = Env->GetLvarName(cntIdxInfo.IdxValue, "Integer"); + Env->Stack[cntIdxInfo.IdxValue] = item; + } + } + else + { + if (varIdxInfo.IdxType == itREG) + { + GetRegItem(varIdxInfo.IdxValue, &item); + if (item.Flags & IF_INTVAL) + { + if (from == "") from = String(item.IntValue); + item.Flags &= ~IF_INTVAL; + } + else + if (from == "") from = item.Value; + item.Value = GetDecompilerRegisterName(varIdxInfo.IdxValue); + item.Flags |= IF_CYCLE_VAR; + SetRegItem(varIdxInfo.IdxValue, &item); + } + else if (varIdxInfo.IdxType == itLVAR) + { + item = Env->Stack[varIdxInfo.IdxValue]; + from = item.Value1; + item.Value = Env->GetLvarName(varIdxInfo.IdxValue, "Integer"); + item.Flags |= IF_CYCLE_VAR; + Env->Stack[varIdxInfo.IdxValue] = item; + } + if (cntIdxInfo.IdxType == itREG) + { + GetRegItem(cntIdxInfo.IdxValue, &item); + if (item.Flags & IF_INTVAL) + { + if (cnt == "") cnt = String(item.IntValue); + item.Flags &= ~IF_INTVAL; + } + else + if (cnt == "") cnt = item.Value; + item.Value = GetDecompilerRegisterName(cntIdxInfo.IdxValue); + SetRegItem(cntIdxInfo.IdxValue, &item); + } + else if (cntIdxInfo.IdxType == itLVAR) + { + cnt = Env->Stack[cntIdxInfo.IdxValue].Value; + Env->Stack[cntIdxInfo.IdxValue].Value = Env->GetLvarName(cntIdxInfo.IdxValue, "Integer"); + } + if (SameText(from, "1")) + to = cnt; + else if (SameText(from, "0")) + to = cnt + " - 1"; + else + { + to = cnt + " + " + from + " - 1"; + } + } + res = new TLoopInfo('F', fromAdr, brkAdr, lastAdr);//for + res->forInfo = new TForInfo(noVar, false, stopAdr, from, to, varIdxInfo.IdxType, varIdxInfo.IdxValue, cntIdxInfo.IdxType, cntIdxInfo.IdxValue); + return res; + } + } + res = new TLoopInfo('R', fromAdr, brkAdr, lastAdr);//repeat + return res; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulatePush(DWORD curAdr, bool bShowComment) +{ + bool _vmt; + int _offset, _idx; + BYTE *_pdi, _b; + ITEM _item, _item1; + PInfoRec _recN; + String _name, _type, _typeName, _value, _regname; + + //push imm + if (DisInfo.OpType[0] == otIMM) + { + if (IsValidImageAdr(DisInfo.Immediate)) + { + _recN = GetInfoRec(DisInfo.Immediate); + if (_recN && (_recN->kind == ikLString || _recN->kind == ikWString || _recN->kind == ikUString)) + { + InitItem(&_item); + _item.Value = _recN->GetName(); + _item.Type = "String"; + Push(&_item); + return; + } + } + + InitItem(&_item); + _item.Flags = IF_INTVAL; + /* + _pdi = (BYTE*)&DisInfo.Immediate; _b = *_pdi; + if (DisInfo.ImmSize == 1)//byte + { + if (_b & 0x80) + _imm = 0xFFFFFF00 | _b; + else + _imm = _b; + } + else if (DisInfo.ImmSize == 2)//word + { + if (_b & 0x80) + _imm = 0xFFFF0000 | _b; + else + _imm = _b; + } + else + { + _imm = DisInfo.Immediate; + } + */ + _item.IntValue = DisInfo.Immediate; + Push(&_item); + return; + } + //push reg + if (DisInfo.OpType[0] == otREG) + { + _idx = DisInfo.OpRegIdx[0]; + //push esp + if (_idx == 20) + { + InitItem(&_item); + _item.Flags = IF_STACK_PTR; + _item.IntValue = _ESP_; + Push(&_item); + return; + } + GetRegItem(_idx, &_item); + + _regname = GetDecompilerRegisterName(_idx); + if (_item.Value != "" && !SameText(_regname, _item.Value)) _value = _item.Value + "{" + _regname + "}"; + _item.Value = _value; + + //push eax - clear flag IF_CALL_RESULT + if (_item.Flags & IF_CALL_RESULT) + { + _item.Flags &= ~IF_CALL_RESULT; + SetRegItem(_idx, &_item); + } + //if (_item.Flags & IF_ARG) + //{ + // _item.Flags &= ~IF_ARG; + // _item.Name = ""; + //} + + Push(&_item); + if (bShowComment) Env->AddToBody("//push " + _regname); + return; + } + //push mem + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_item, OP_PUSH); + Push(&_item); + return; + _offset = DisInfo.Offset; + //push [BaseReg + IndxReg*Scale + Offset] + if (DisInfo.BaseReg != -1) + { + if (DisInfo.BaseReg == 20) + { + _item = Env->Stack[_ESP_ + _offset]; + Push(&_item); + return; + } + + GetRegItem(DisInfo.BaseReg, &_item1); + //cop reg, [BaseReg + Offset] + if (DisInfo.IndxReg == -1) + { + //push [ebp-N] + if (_item1.Flags & IF_STACK_PTR) + { + _name = Env->GetLvarName(_item1.IntValue + _offset, ""); + _item = Env->Stack[_item1.IntValue + _offset]; + _item.Value = _name; + Push(&_item); + return; + } + //push [reg] + if (!_offset) + { + //var + if (_item1.Flags & IF_VAR) + { + InitItem(&_item); + _item.Value = _item1.Value; + _item.Type = _item1.Type; + Push(&_item); + return; + } + if (IsValidImageAdr(_item1.IntValue)) + { + _recN = GetInfoRec(_item1.IntValue); + if (_recN) + { + InitItem(&_item); + _item.Value = _recN->GetName(); + _item.Type = _recN->type; + Push(&_item); + return; + } + } + } + _typeName = TrimTypeName(GetRegType(DisInfo.BaseReg)); + if (_typeName != "") + { + if (_typeName[1] == '^') //Pointer to gvar (from other unit) + { + InitItem(&_item); + _item.Value = _item1.Value; + _item.Type = GetTypeDeref(_typeName); + Push(&_item); + return; + } + //push [reg+N] + if (GetField(_typeName, _offset, _name, _type) >= 0) + { + InitItem(&_item); + + if (SameText(_item1.Value, "Self")) + _item.Value = _name; + else + _item.Value = _item1.Value + "." + _name; + + _item.Type = _type; + Push(&_item); + return; + } + } + } + } + //[Offset] + if (IsValidImageAdr(_offset)) + { + _recN = GetInfoRec(_offset); + if (_recN) + { + InitItem(&_item); + _item.Value = _recN->GetName(); + _item.Type = _recN->type; + Push(&_item); + return; + } + InitItem(&_item); + Push(&_item); + return; + } + else + { + Env->ErrAdr = curAdr; + throw Exception("Address is outside program image"); + } + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulatePop(DWORD curAdr) +{ + String _regname; + PITEM _item; + + //pop reg + if (DisInfo.OpType[0] == otREG) + { + _item = Pop(); + if (!IsFlagSet(cfFrame, Adr2Pos(curAdr))) + { + _regname = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]); + //_line = _regname + " := "; + //if (_item->Flags & IF_ARG) + // _line += _item->Name; + //else + // _line += _item->Value; + Env->AddToBody("//pop " + _regname); + } + _item->Precedence = PRECEDENCE_NONE; + if (!_item->Value.Pos(_regname)) + _item->Value += "{" + _regname + "}"; + SetRegItem(DisInfo.OpRegIdx[0], _item); + return; + } + //pop mem + if (DisInfo.OpType[0] == otMEM) + { + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +//Simulate instruction with 1 operand +void __fastcall TDecompiler::SimulateInstr1(DWORD curAdr, BYTE Op) +{ + int _regIdx, _offset; + ITEM _item, _item1, _item2, _itemBase, _itemSrc; + String _name, _value, _line, _comment; + + //op reg + if (DisInfo.OpType[0] == otREG) + { + _regIdx = DisInfo.OpRegIdx[0]; + if (Op == OP_INC) + { + GetRegItem(_regIdx, &_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = _item.Value + " + 1"; + SetRegItem(_regIdx, &_item); + _line = GetDecompilerRegisterName(_regIdx) + " := " + GetDecompilerRegisterName(_regIdx) + " + 1;"; + if (_item.Value != "") _line += "//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_DEC) + { + GetRegItem(_regIdx, &_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = _item.Value + " - 1"; + SetRegItem(_regIdx, &_item); + _line = GetDecompilerRegisterName(_regIdx) + " := " + GetDecompilerRegisterName(_regIdx) + " - 1;"; + if (_item.Value != "") _line += "//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_IMUL) + { + GetRegItem(_regIdx, &_item1); + GetRegItem(16, &_item2); + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = _item1.Value + " * " + _item2.Value; + _item.Type = "Int64"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := " + GetDecompilerRegisterName(_regIdx) + " * " + "EAX;"; + if (_item.Value != "") _line += "//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_NEG) + { + GetRegItem(_regIdx, &_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "-" + _item.Value; + SetRegItem(_regIdx, &_item); + _line = GetDecompilerRegisterName(_regIdx) + " := -" + GetDecompilerRegisterName(_regIdx) + ";"; + if (_item.Value != "") _line += "//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_NOT) + { + GetRegItem(_regIdx, &_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "not " + _item.Value; + SetRegItem(_regIdx, &_item); + _line = GetDecompilerRegisterName(_regIdx) + " := not " + GetDecompilerRegisterName(_regIdx) + ";"; + if (_item.Value != "") _line += "//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_SET) + { + InitItem(&_item); + _item.Value = CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R; + _item.Type = "Boolean"; + SetRegItem(_regIdx, &_item); + _line = GetDecompilerRegisterName(_regIdx) + " := " + "(" + _item.Value + ");"; + Env->AddToBody(_line); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } + //op mem + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, Op); + if (_itemSrc.Name != "") + _value = _itemSrc.Name; + else + _value = _itemSrc.Value; + if (Op == OP_IMUL) + { + GetRegItem(16, &_item1); + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = _value + " * " + _item1.Value;; + _item.Type = "Int64"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := " + _item.Value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_SET) + { + _line = _value + " := (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ");"; + Env->AddToBody(_line); + return; + } + if (Op == OP_NEG) + { + _line = _value + " := -" + _value + ";"; + Env->AddToBody(_line); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + + _offset = DisInfo.Offset; + if (DisInfo.BaseReg != -1) + { + if (DisInfo.IndxReg == -1) + { + GetRegItem(DisInfo.BaseReg, &_itemBase); + //op [esp+N] + if (DisInfo.BaseReg == 20) + { + if (Op == OP_IMUL) + { + _item1 = Env->Stack[_ESP_ + _offset]; + GetRegItem(16, &_item2); + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = _item1.Value + " * " + _item2.Value; + _item.Type = "Integer"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := EAX * " + Env->GetLvarName(_ESP_ + _offset, "Integer") + ";//" + _item1.Value; + Env->AddToBody(_line); + return; + } + } + //op [ebp-N] + if (DisInfo.BaseReg == 21 && (_itemBase.Flags & IF_STACK_PTR)) + { + if (Op == OP_IMUL) + { + _item1 = Env->Stack[_itemBase.IntValue + _offset]; + GetRegItem(16, &_item2); + if (_item1.Value != "") + _name = _item1.Value; + else + _name = Env->GetLvarName(_itemBase.IntValue + _offset, "Integer"); + + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = _name + " * " + _item2.Value; + _item.Type = "Integer"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := EAX * " + Env->GetLvarName(_ESP_ + _offset, "Integer") + ";//" + _item.Value; + Env->AddToBody(_line); + return; + } + } + if (_itemBase.Type[1] == '^') //Pointer to gvar (from other unit) + { + if (Op == OP_IMUL) + { + GetRegItem(16, &_item2); + + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = GetString(&_item2, PRECEDENCE_MULT) + " * " + GetString(&_itemBase, PRECEDENCE_MULT + 1); + _item.Type = "Integer"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := EAX * " + _itemBase.Value + ";//" + _item.Value; + Env->AddToBody(_line); + return; + } + } + } + } + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateInstr2RegImm(DWORD curAdr, BYTE Op) +{ + bool _vmt, _ptr; + BYTE _kind, _kind1, _kind2; + char *_tmpBuf; + int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size; + int _idx, _classSize, _dotpos, _len, _ap; + DWORD _adr; + ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; + ITEM _item, _item1, _item2; + PInfoRec _recN, _recN1; + PLOCALINFO _locInfo; + String _name, _type, _value, _typeName, _line, _comment, _imm, _iname, _fname, _text; + WideString _wStr; + + _reg1Idx = DisInfo.OpRegIdx[0]; + _imm = GetImmString(DisInfo.Immediate); + if (Op == OP_MOV) + { + InitItem(&_item); + _item.Flags = IF_INTVAL; + _item.IntValue = DisInfo.Immediate; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _imm + ";"; + Env->AddToBody(_line); + return; + + if (IsValidImageAdr(DisInfo.Immediate)) + { + _ap = Adr2Pos(DisInfo.Immediate); + if (_ap >= 0) + { + _recN = GetInfoRec(DisInfo.Immediate); + if (_recN) + { + _kind1 = _recN->kind; + if (_kind1 == ikPointer) + { + _item.Flags = IF_INTVAL; + _item.IntValue = DisInfo.Immediate; + SetRegItem(_reg1Idx, &_item); + return; + } + if (_kind1 == ikUnknown || _kind1 == ikData) _kind1 = GetTypeKind(_recN->type, &_size); + + switch (_kind1) + { + case ikSet: + _item.Flags = IF_INTVAL; + _item.IntValue = DisInfo.Immediate; + _item.Value = GetDecompilerRegisterName(_reg1Idx); + _item.Type = _recN->type; + break; + case ikString: + _item.Value = _recN->GetName(); + _item.Type = "ShortString"; + break; + case ikLString: + _item.Value = _recN->GetName(); + _item.Type = "String"; + break; + case ikWString: + _item.Value = _recN->GetName(); + _item.Type = "WideString"; + break; + case ikUString: + _item.Value = _recN->GetName(); + _item.Type = "UnicodeString"; + break; + case ikCString: + _item.Value = _recN->GetName(); + _item.Type = "PChar"; + break; + case ikWCString: + _len = wcslen((wchar_t*)(Code + _ap)); + _wStr = WideString((wchar_t*)(Code + _ap)); + _size = WideCharToMultiByte(CP_ACP, 0, _wStr, _len, 0, 0, 0, 0); + if (_size) + { + _tmpBuf = new char[_size + 1]; + WideCharToMultiByte(CP_ACP, 0, _wStr, _len, (LPSTR)_tmpBuf, _size, 0, 0); + _recN->SetName(TransformString(_tmpBuf, _size)); + delete[] _tmpBuf; + } + _item.Value = _recN->GetName(); + _item.Type = "PWideChar"; + break; + case ikResString: + Env->LastResString = _recN->rsInfo->value; + _item.Value = _recN->GetName(); + _item.Type = "PResStringRec"; + break; + case ikArray: + _item.Value = _recN->GetName(); + _item.Type = _recN->type; + break; + case ikDynArray: + _item.Value = _recN->GetName(); + _item.Type = _recN->type; + break; + default: + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } + SetRegItem(_reg1Idx, &_item); + return; + } + } + else + { + _idx = BSSInfos->IndexOf(Val2Str8(DisInfo.Immediate)); + if (_idx != -1) + { + _recN = (PInfoRec)BSSInfos->Objects[_idx]; + _item.Value = _recN->GetName(); + _item.Type = _recN->type; + } + else + { + _item.Value = MakeGvarName(DisInfo.Immediate); + AddToBSSInfos(DisInfo.Immediate, _item.Value, ""); + } + SetRegItem(_reg1Idx, &_item); + return; + } + } + _item.Flags = IF_INTVAL; + _item.IntValue = DisInfo.Immediate; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _imm + ";"; + Env->AddToBody(_line); + return; + } + //cmp reg, imm + if (Op == OP_CMP) + { + GetRegItem(_reg1Idx, &_item); + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + if (_item.Value != "" && !SameText(_item.Value, CmpInfo.L)) + CmpInfo.L += "{" + _item.Value + "}"; + CmpInfo.O = CmpOp; + CmpInfo.R = GetImmString(_item.Type, DisInfo.Immediate); + return; + } + //test reg, imm + if (Op == OP_TEST) + { + GetRegItem(_reg1Idx, &_item); + _kind = GetTypeKind(_item.Type, &_size); + if (_kind == ikSet) + { + CmpInfo.L = GetSetString(_item.Type, (BYTE*)&DisInfo.Immediate); + CmpInfo.O = CmpOp + 12;//look GetDirectCondition (in) + CmpInfo.R = GetDecompilerRegisterName(_reg1Idx); + return; + } + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx) + " And " + _imm; + CmpInfo.O = CmpOp; + CmpInfo.R = "0"; + return; + } + //add reg, imm (points to class field) + if (Op == OP_ADD) + { + //add esp, imm + if (_reg1Idx == 20) + { + _ESP_ += (int)DisInfo.Immediate; + return; + } + //add reg, imm + GetRegItem(_reg1Idx, &_item1); + //If stack ptr + if (_item1.Flags & IF_STACK_PTR) + { + _item1.IntValue += (int)DisInfo.Immediate; + SetRegItem(_reg1Idx, &_item1); + return; + } + if (_item1.Type != "") + { + _typeName = _item1.Type; + _ptr = (_item1.Type[1] == '^'); + if (_ptr) _typeName = GetTypeDeref(_item1.Type); + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikRecord) + { + InitItem(&_item); + _value = _item1.Value; + + if (_ptr) _value += "^"; + if (GetField(_typeName, DisInfo.Immediate, _name, _type) >= 0) + { + _value += "." + _name; + _typeName = _type; + } + else + { + _value += ".f" + Val2Str0(DisInfo.Immediate); + _typeName = _type; + } + _item.Value = _value; + _item.Type = _typeName; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item.Value; + Env->AddToBody(_line); + return; + } + if (_kind == ikVMT) + { + if (GetField(_item1.Type, DisInfo.Immediate, _name, _type) >= 0) + { + InitItem(&_item); + + if (SameText(_item1.Value, "Self")) + _item.Value = _name; + else + _item.Value = _item1.Value + "." + _name; + + _item.Type = _type; + + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item.Value; + Env->AddToBody(_line); + return; + } + } + } + if (_item1.Value != "") + _value = GetString(&_item1, PRECEDENCE_ADD) + " + " + _imm; + else + _value = GetDecompilerRegisterName(_reg1Idx) + " + " + _imm; + //-1 and +1 for cycles + if (DisInfo.Immediate == 1 && _item1.Value != "") + { + _len = _item1.Value.Length(); + if (_len > 4) + { + if (SameText(_item1.Value.SubString(_len - 3, 4), " - 1")) + { + _item1.Value = _item1.Value.SubString(1, _len - 4); + _item1.Precedence = PRECEDENCE_NONE; + SetRegItem(_reg1Idx, &_item1); + return; + } + } + } + + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + CmpInfo.O = CmpOp; + CmpInfo.R = 0; + + InitItem(&_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = GetDecompilerRegisterName(_reg1Idx); + SetRegItem(_reg1Idx, &_item); + + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " + " + _imm; + _comment = _item.Value; + Env->AddToBody(_line + ";//" + _comment); + return; + } + //sub reg, imm + if (Op == OP_SUB) + { + //sub esp, imm + if (_reg1Idx == 20) + { + _ESP_ -= (int)DisInfo.Immediate; + return; + } + GetRegItem(_reg1Idx, &_item1); + //If reg point to VMT - return (may be operation with Interface) + if (GetTypeKind(_item1.Type, &_size) == ikVMT) return; + + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + CmpInfo.O = CmpOp; + CmpInfo.R = 0; + + InitItem(&_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = GetDecompilerRegisterName(_reg1Idx); + SetRegItem(_reg1Idx, &_item); + + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " - " + _imm; + _comment = _item.Value; + Env->AddToBody(_line + ";//" + _comment); + return; + } + //and reg, imm + if (Op == OP_AND) + { + GetRegItem(_reg1Idx, &_item1); + if (DisInfo.Immediate == 0xFF && SameText(_item1.Type, "Byte")) return; + + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " And " + _imm; + SetRegItem(_reg1Idx, &_item); + + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " And " + _imm; + _comment = _item.Value; + Env->AddToBody(_line + ";//" + _comment); + return; + } + //or reg, imm + if (Op == OP_OR) + { + GetRegItem(_reg1Idx, &_item1); + InitItem(&_item); + if (DisInfo.Immediate == -1) + { + _item.Flags = IF_INTVAL; + _item.IntValue = -1; + _item.Type = "Cardinal"; + } + else + { + _item.Precedence = PRECEDENCE_ADD; + _item.Value = GetString(&_item1, PRECEDENCE_ADD) + " Or " + _imm; + _item.Type = "Cardinal"; + } + SetRegItem(_reg1Idx, &_item); + + _line = GetDecompilerRegisterName(_reg1Idx) + " := "; + if (DisInfo.Immediate != -1) + _line += GetDecompilerRegisterName(_reg1Idx) + " Or "; + _line += _imm; + Env->AddToBody(_line + ";"); + return; + } + //sal(shl) reg, imm + if (Op == OP_SAL || Op == OP_SHL) + { + _pow2 = 1; + for (int n = 0; n < DisInfo.Immediate; n++) _pow2 *= 2; + GetRegItem(_reg1Idx, &_item1); + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + if (Op == OP_SHL) + { + _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Shl " + String(DisInfo.Immediate); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Shl " + String(DisInfo.Immediate); + _comment = GetString(&_item1, PRECEDENCE_MULT) + " * " + String(_pow2); + } + else + { + _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " * " + String(_pow2); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " * " + String(_pow2); + _comment = ""; + } + SetRegItem(_reg1Idx, &_item); + if (_comment != "") _line += ";//" + _comment; + Env->AddToBody(_line); + return; + } + //sar(shr) reg, imm + if (Op == OP_SAR || Op == OP_SHR) + { + _pow2 = 1; + for (int n = 0; n < DisInfo.Immediate; n++) _pow2 *= 2; + GetRegItem(_reg1Idx, &_item1); + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + if (Op == OP_SHR) + { + _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Shr " + String(DisInfo.Immediate); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Shr " + String(DisInfo.Immediate); + _comment = GetString(&_item1, PRECEDENCE_MULT) + " Div " + String(_pow2); + } + else + { + _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Div " + String(_pow2); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + String(_pow2); + _comment = ""; + } + SetRegItem(_reg1Idx, &_item); + if (_comment != "") _line += ";//" + _comment; + Env->AddToBody(_line); + return; + } + //xor reg, imm + if (Op == OP_XOR) + { + GetRegItem(_reg1Idx, &_item1); + InitItem(&_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = GetString(&_item1, PRECEDENCE_ADD) + " Xor " + _imm; + SetRegItem(_reg1Idx, &_item); + + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Xor " + _imm; + _comment = _item.Value; + Env->AddToBody(_line + ";//" + _comment); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateInstr2RegReg(DWORD curAdr, BYTE Op) +{ + bool _vmt; + BYTE _kind; + int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _classSize, _dotpos; + DWORD _adr; + ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; + ITEM _item, _item1, _item2; + PInfoRec _recN, _recN1; + PLOCALINFO _locInfo; + PFIELDINFO _fInfo; + String _name, _value, _typeName, _line, _comment, _imm, _iname, _fname, _op; + + _reg1Idx = DisInfo.OpRegIdx[0]; + _reg2Idx = DisInfo.OpRegIdx[1]; + GetRegItem(_reg1Idx, &_item1); + GetRegItem(_reg2Idx, &_item2); + + if (Op == OP_MOV) + { + if (IsSameRegister(_reg1Idx, _reg2Idx)) return; + + //mov esp, reg + if (_reg1Idx == 20) + { + SetRegItem(20, &_item2); + return; + } + //mov reg, esp + if (_reg2Idx == 20) + { + InitItem(&_item); + _item.Flags = IF_STACK_PTR; + _item.IntValue = _ESP_; + SetRegItem(_reg1Idx, &_item); + //mov ebp, esp + if (Env->BpBased && _reg1Idx == 21 && !Env->LocBase) Env->LocBase = _ESP_; + return; + } + //mov reg, reg + if (_item2.Flags & IF_ARG) + { + if (_reg1Idx != _reg2Idx) + { + _item2.Flags &= ~IF_ARG; + _item2.Name = ""; + SetRegItem(_reg1Idx, &_item2); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item2.Value + ";"; + Env->AddToBody(_line); + } + return; + } + //mov reg, eax (eax - call result) -> set eax to reg!!!! + if (_item2.Flags & IF_CALL_RESULT) + { + _item2.Flags &= ~IF_CALL_RESULT; + _item2.Value1 = _item2.Value; + _item2.Value = GetDecompilerRegisterName(_reg1Idx); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item2.Value1 + ";"; + SetRegItem(_reg1Idx, &_item2); + Env->AddToBody(_line); + return; + } + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg2Idx) + ";"; + if (_item2.Value != "") + _line += "//" + _item2.Value; + _item2.Flags = 0; + if (_item2.Value == "") + _item2.Value = GetDecompilerRegisterName(_reg2Idx); + SetRegItem(_reg1Idx, &_item2); + Env->AddToBody(_line); + return; + } + //cmp reg, reg + if (Op == OP_CMP) + { + //_kind1 = GetTypeKind(_item1.Type, &_size); + //_kind2 = GetTypeKind(_item2.Type, &_size); + //!!! if kind1 <> kind2 ??? + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + if (_item1.Value != "" && !SameText(_item1.Value, CmpInfo.L)) + CmpInfo.L += "{" + _item1.Value + "}"; + CmpInfo.O = CmpOp; + CmpInfo.R = GetDecompilerRegisterName(_reg2Idx); + if (_item2.Value != "" && !SameText(_item2.Value, CmpInfo.R)) + CmpInfo.R += "{" + _item2.Value + "}"; + return; + } + if (Op == OP_TEST) + { + if (_reg1Idx == _reg2Idx) + { + //GetRegItem(_reg1Idx, &_item); + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + if (_item1.Value != "" && !SameText(_item1.Value, CmpInfo.L)) + CmpInfo.L += "{" + _item1.Value + "}"; + CmpInfo.O = CmpOp; + CmpInfo.R = GetImmString(_item1.Type, (Variant)0); + return; + } + else + { + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx) + " And " + GetDecompilerRegisterName(_reg2Idx); + CmpInfo.O = CmpOp; + CmpInfo.R = "0"; + return; + } + } + if (Op == OP_ADD) + _op = " + "; + else if (Op == OP_SUB) + _op = " - "; + else if (Op == OP_OR) + _op = " Or "; + else if (Op == OP_XOR) + _op = " Xor "; + else if (Op == OP_MUL || Op == OP_IMUL) + _op = " * "; + else if (Op == OP_AND) + _op = " And "; + else if (Op == OP_SHR) + _op = " Shr "; + else if (Op == OP_SHL) + _op = " Shl "; + + if (Op == OP_ADD || Op == OP_SUB || Op == OP_OR || Op == OP_XOR) + { + if (Op == OP_XOR && _reg1Idx == _reg2Idx)//xor reg,reg + { + Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := 0;"); + InitItem(&_item); + _item.Flags = IF_INTVAL; + _item.IntValue = 0; + SetRegItem(_reg1Idx, &_item); + return; + } + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + GetDecompilerRegisterName(_reg2Idx); + _comment = GetString(&_item1, PRECEDENCE_ADD) + _op + GetString(&_item2, PRECEDENCE_ADD + 1); + Env->AddToBody(_line + ";//" + _comment); + + InitItem(&_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = GetDecompilerRegisterName(_reg1Idx); + SetRegItem(_reg1Idx, &_item); + + if (Op == OP_SUB) + { + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + CmpInfo.O = CmpOp; + CmpInfo.R = GetDecompilerRegisterName(_reg2Idx); + } + return; + } + if (Op == OP_MUL || Op == OP_IMUL || Op == OP_AND || Op == OP_SHR || Op == OP_SHL) + { + _line += GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + GetDecompilerRegisterName(_reg2Idx); + _comment = GetString(&_item1, PRECEDENCE_MULT) + _op + GetString(&_item2, PRECEDENCE_MULT + 1); + Env->AddToBody(_line + ";//" + _comment); + + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = _comment; + _item.Type = "Integer"; + SetRegItem(_reg1Idx, &_item); + return; + } + if (Op == OP_DIV || Op == OP_IDIV) + { + _line = "EAX := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + GetDecompilerRegisterName(_reg2Idx); + _comment = GetString(&_item1, PRECEDENCE_MULT) + " Div " + GetString(&_item2, PRECEDENCE_MULT + 1); + Env->AddToBody(_line + ";//" + _comment); + + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = _comment; + _item.Type = "Integer"; + SetRegItem(16, &_item); + _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Mod " + GetString(&_item2, PRECEDENCE_MULT + 1); + SetRegItem(18, &_item); + return; + } + if (Op == OP_XCHG) + { + SetRegItem(_reg1Idx, &_item2); + SetRegItem(_reg2Idx, &_item1); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateInstr2RegMem(DWORD curAdr, BYTE Op) +{ + bool _vmt; + BYTE _kind, _kind1, _kind2; + int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _idx1, _classSize, _ap; + DWORD _adr; + ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; + ITEM _item, _item1, _item2; + PInfoRec _recN, _recN1; + PLOCALINFO _locInfo; + PFIELDINFO _fInfo; + String _name, _value, _type, _line, _comment, _imm, _iname, _fname, _op; + + _reg1Idx = DisInfo.OpRegIdx[0]; + GetRegItem(_reg1Idx, &_itemDst); + + GetMemItem(curAdr, &_itemSrc, Op); + if ((_itemSrc.Flags & IF_VMT_ADR) || (_itemSrc.Flags & IF_EXTERN_VAR)) + { + SetRegItem(_reg1Idx, &_itemSrc); + return; + } + _op = "?"; + if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || Op == OP_OR || Op == OP_AND || Op == OP_XOR) + { + if (Op == OP_ADD) + _op = " + "; + else if (Op == OP_SUB) + _op = " - "; + else if (Op == OP_MUL || Op == OP_IMUL) + _op = " * "; + else if (Op == OP_OR) + _op = " Or "; + else if (Op == OP_AND) + _op = " And "; + else if (Op == OP_XOR) + _op = " Xor "; + } + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemSrc.IntValue]; + if (Op == OP_MOV) + { + //Arg + if (_item.Flags & IF_ARG) + { + //_item.Flags &= ~IF_VAR; + _item.Value = _item.Name; + SetRegItem(_reg1Idx, &_item); + Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := " + _item.Value + ";"); + return; + } + //Var + if (_item.Flags & IF_VAR) + { + //_item.Flags &= ~IF_VAR; + SetRegItem(_reg1Idx, &_item); + return; + } + //Field + if (_item.Flags & IF_FIELD) + { + _foffset = _item.Offset; + _fname = GetRecordFields(_foffset, Env->Stack[_itemSrc.IntValue - _foffset].Type); + _name = Env->Stack[_itemSrc.IntValue - _foffset].Value; + _type = ExtractType(_fname); + if (_name == "") + _name = Env->GetLvarName(_itemSrc.IntValue - _foffset, _type); + InitItem(&_itemDst); + if (_fname.Pos(":")) + { + _itemDst.Value = _name + "." + ExtractName(_fname); + _itemDst.Type = _type; + } + else + { + _itemDst.Value = _name + ".f" + Val2Str0(_foffset); + } + SetRegItem(_reg1Idx, &_itemDst); + Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := " + _itemDst.Value + ";"); + return; + } + + if (_item.Name != "") + _value = _item.Name; + else + { + _value = Env->GetLvarName(_itemSrc.IntValue, ""); + if (_item.Value != "") + _value += "{" + _item.Value + "}"; + } + _item.Value = _value; + + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_LEA) + { + SetRegItem(_reg1Idx, &_itemSrc); + return; + } + if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || Op == OP_OR || Op == OP_AND) + { + //Field + if (_item.Flags & IF_FIELD) + { + _foffset = _item.Offset; + _fname = GetRecordFields(_foffset, Env->Stack[_itemSrc.IntValue - _foffset].Type); + _name = Env->Stack[_itemSrc.IntValue - _foffset].Value; + + _itemDst.Flags = 0; + _itemDst.Precedence = PRECEDENCE_ADD; + if (_fname.Pos(":")) + { + _itemDst.Value += _op + _name + "." + ExtractName(_fname); + _itemDst.Type = ExtractType(_fname); + } + else + { + _itemDst.Value += _op + _name + ".f" + Val2Str0(_foffset); + } + SetRegItem(_reg1Idx, &_itemDst); + Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := " + _itemDst.Value + ";"); + return; + } + if (_itemSrc.Name != "") + _name = _itemSrc.Name; + else + _name = _itemSrc.Value; + + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _name + ";"; + _itemDst.Flags = 0; + if (Op == OP_ADD || Op == OP_SUB || Op == OP_OR) + _itemDst.Precedence = PRECEDENCE_ADD; + else if (Op == OP_MUL || Op == OP_IMUL || Op == OP_AND) + _itemDst.Precedence = PRECEDENCE_MULT; + _itemDst.Value = GetDecompilerRegisterName(_reg1Idx); + SetRegItem(_reg1Idx, &_itemDst); + Env->AddToBody(_line); + if (Op == OP_OR || Op == OP_AND) + { + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + CmpInfo.O = CmpOp; + CmpInfo.R = "0"; + } + return; + } + if (Op == OP_CMP) + { + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + if (_itemDst.Value != "" && !SameText(_itemDst.Value, CmpInfo.L)) + CmpInfo.L += "{" + _itemDst.Value + "}"; + CmpInfo.O = CmpOp; + if (_item.Flags & IF_ARG) + CmpInfo.R = _item.Name; + else + CmpInfo.R = _itemSrc.Value; + return; + } + if (Op == OP_XCHG) + { + SetRegItem(_reg1Idx, &_item); + Env->Stack[_itemSrc.IntValue] = _itemDst; + return; + } + } + if (_itemSrc.Flags & IF_INTVAL) + { + _offset = _itemSrc.IntValue; + if (Op == OP_MOV || Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || Op == OP_DIV || Op == OP_IDIV) + { + _name = ""; + _type = ""; + _ap = Adr2Pos(_offset); _recN = GetInfoRec(_offset); + if (_recN) + { + //VMT + if (_recN->kind == ikVMT || _recN->kind == ikDynArray) + { + InitItem(&_item); + _item.Flags = IF_INTVAL; + _item.IntValue = _offset; + _item.Value = _recN->GetName(); + _item.Type = _recN->GetName(); + SetRegItem(_reg1Idx, &_item); + return; + } + MakeGvar(_recN, _offset, curAdr); + _name = _recN->GetName(); + _type = _recN->type; + + if (_ap >= 0) + { + _adr = *(DWORD*)(Code + _ap); + //May be pointer to var + if (IsValidImageAdr(_adr)) + { + _recN1 = GetInfoRec(_adr); + if (_recN1) + { + MakeGvar(_recN1, _offset, curAdr); + InitItem(&_item); + _item.Value = _recN1->GetName(); + _item.Type = "^" + _recN1->type; + SetRegItem(_reg1Idx, &_item); + return; + } + } + } + } + //Just value + else + { + InitItem(&_item); + _item.Flags = IF_INTVAL; + _item.IntValue = _offset; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _offset + ";"; + Env->AddToBody(_line); + return; + } + + if (Op == OP_MOV) + { + InitItem(&_item); + _item.Value = _name; + _item.Type = _type; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _name + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL) + { + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _name + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_DIV || Op == OP_IDIV) + { + _line = GetDecompilerRegisterName(16) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + _name + ";"; + Env->AddToBody(_line); + _line = GetDecompilerRegisterName(18) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Mod " + _name + ";"; + Env->AddToBody(_line); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } + if (Op == OP_CMP) + { + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + if (_itemDst.Value != "" && !SameText(_itemDst.Value, CmpInfo.L)) + CmpInfo.L += "{" + _itemDst.Value + "}"; + CmpInfo.O = CmpOp; + _recN = GetInfoRec(_offset); + if (_recN) + CmpInfo.R = _recN->GetName(); + else + CmpInfo.R = MakeGvarName(_offset); + return; + } + } + if (Op == OP_MOV || Op == OP_LEA) + { + SetRegItem(_reg1Idx, &_itemSrc); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _itemSrc.Value; + if (_itemSrc.Flags & IF_RECORD_FOFS) + { + _line += "." + GetRecordFields(_itemSrc.Offset, _itemSrc.Type); + } + _line += ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_CMP) + { + CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); + if (_itemDst.Value != "" && !SameText(_itemDst.Value, CmpInfo.L)) + CmpInfo.L += "{" + _itemDst.Value + "}"; + CmpInfo.O = CmpOp; + CmpInfo.R = _itemSrc.Value; + return; + } + if (Op == OP_ADD || Op == OP_SUB || Op == OP_XOR) + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ADD; + _item.Value = GetString(&_itemDst, PRECEDENCE_ADD) + _op + GetString(&_itemSrc, PRECEDENCE_ADD + 1); + _item.Type = _itemSrc.Type; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _itemSrc.Value + ";//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_MUL || Op == OP_IMUL || Op == OP_AND) + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = GetString(&_itemDst, PRECEDENCE_MULT) + _op + GetString(&_itemSrc, PRECEDENCE_MULT + 1); + _item.Type = _itemSrc.Type; + SetRegItem(_reg1Idx, &_item); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _itemSrc.Value + ";//" + _item.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_DIV || Op == OP_IDIV) + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = GetString(&_itemDst, PRECEDENCE_MULT) + " Div " + GetString(&_itemSrc, PRECEDENCE_MULT + 1); + _item.Type = _itemSrc.Type; + SetRegItem(16, &_item); + + InitItem(&_item); + _item.Precedence = PRECEDENCE_MULT; + _item.Value = GetString(&_itemDst, PRECEDENCE_MULT) + " Mod " + GetString(&_itemSrc, PRECEDENCE_MULT + 1); + _itemDst.Type = _itemSrc.Type; + SetRegItem(18, &_item); + + _line = GetDecompilerRegisterName(16) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + _itemSrc.Value + ";//" + _itemDst.Value + " Div " + _itemSrc.Value; + Env->AddToBody(_line); + _line = GetDecompilerRegisterName(18) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Mod " + _itemSrc.Value + ";//" + _itemDst.Value + " Div " + _itemSrc.Value; + Env->AddToBody(_line); + return; + } + if (Op == OP_OR) + { + //Dst - Set + if (GetTypeKind(_itemDst.Type, &_size) == ikSet) + { + AssignItem(&_item1, &_itemDst); + AssignItem(&_item2, &_itemSrc); + } + //Src - Set + if (GetTypeKind(_itemSrc.Type, &_size) == ikSet) + { + AssignItem(&_item1, &_itemSrc); + AssignItem(&_item2, &_itemDst); + } + _line = _item1.Value + " := " + _item1.Value + " + "; + if (_item2.Flags & IF_INTVAL) + { + if (IsValidImageAdr(_item2.IntValue)) + _line += GetSetString(_item1.Type, Code + Adr2Pos(_item2.IntValue)); + else + _line += GetSetString(_item1.Type, (BYTE*)&_item2.IntValue); + } + else + _line += _item2.Value; + _line += ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_XCHG) + { + SetRegItem(_reg1Idx, &_itemSrc); + Env->Stack[_itemSrc.IntValue] = _itemDst; + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateInstr2MemImm(DWORD curAdr, BYTE Op) +{ + bool _vmt; + BYTE _kind, _kind1, _kind2; + int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _idx1, _classSize, _ap; + DWORD _adr; + ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; + ITEM _item, _item1, _item2; + PInfoRec _recN, _recN1; + PLOCALINFO _locInfo; + PFIELDINFO _fInfo; + String _name, _value, _typeName, _line, _comment, _imm, _iname, _fname, _key, _type, _op; + + _imm = GetImmString(DisInfo.Immediate); + GetMemItem(curAdr, &_itemDst, Op); + if (_itemDst.Flags & IF_STACK_PTR) + { + if (_itemDst.Name != "") + _name = _itemDst.Name; + else + _name = _itemDst.Value; + _item = Env->Stack[_itemDst.IntValue]; + if (_item.Flags & IF_ARG) + _name = _item.Value; + if (Op == OP_MOV) + { + Env->Stack[_itemDst.IntValue].Value1 = _imm; + _line = _name + " := " + _imm + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_CMP) + { + CmpInfo.L = _name; + CmpInfo.O = CmpOp; + CmpInfo.R = GetImmString(_item.Type, DisInfo.Immediate); + return; + } + if (Op == OP_TEST) + { + _typeName = TrimTypeName(Env->Stack[_itemDst.IntValue].Type); + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikSet) + { + CmpInfo.L = GetSetString(_typeName, (BYTE*)&DisInfo.Immediate); + CmpInfo.O = CmpOp + 12; + CmpInfo.R = _name; + return; + } + + CmpInfo.L = _name + " And " + _imm; + CmpInfo.O = CmpOp; + CmpInfo.R = "0"; + return; + } + if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || + Op == OP_AND || Op == OP_OR || Op == OP_XOR || Op == OP_SHL || Op == OP_SHR) + { + if (Op == OP_ADD) + _op = " + "; + else if (Op == OP_SUB) + _op = " - "; + else if (Op == OP_MUL || Op == OP_IMUL) + _op = " * "; + else if (Op == OP_AND) + _op = " And "; + else if (Op == OP_OR) + _op = " Or "; + else if (Op == OP_XOR) + _op = " Xor "; + else if (Op == OP_SHL) + _op = " Shl "; + else if (Op == OP_SHR) + _op = " Shr "; + else + _op = " ? "; + + Env->Stack[_itemDst.IntValue].Value = _name; + _line = _name + " := " + _name + _op + _imm + ";"; + Env->AddToBody(_line); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } + if (_itemDst.Flags & IF_INTVAL) + { + if (IsValidImageAdr(_itemDst.IntValue)) + { + _name = MakeGvarName(_itemDst.IntValue); + _ap = Adr2Pos(_itemDst.IntValue); + if (_ap >= 0) + { + _recN = GetInfoRec(_itemDst.IntValue); + if (_recN) + { + if (_recN->HasName()) _name = _recN->GetName(); + if (_recN->type != "") _imm = GetImmString(_recN->type, DisInfo.Immediate); + } + } + else + { + _idx = BSSInfos->IndexOf(Val2Str8(_itemDst.IntValue)); + if (_idx != -1) + { + _recN = (PInfoRec)BSSInfos->Objects[_idx]; + _name = _recN->GetName(); + _type = _recN->type; + if (_type != "") _imm = GetImmString(_type, DisInfo.Immediate); + } + else + { + AddToBSSInfos(_itemDst.IntValue, _name, ""); + } + } + if (Op == OP_MOV) + { + _line = _name + " := " + _imm + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_CMP) + { + CmpInfo.L = _name; + CmpInfo.O = CmpOp; + CmpInfo.R = _imm; + return; + } + if (Op == OP_ADD) + { + _line = _name + " := " + _name + " + " + _imm + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_SUB) + { + _line = _name + " := " + _name + " - " + _imm + ";"; + Env->AddToBody(_line); + return; + } + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } + if (_itemDst.Name != "" && !IsDefaultName(_itemDst.Name)) + _name = _itemDst.Name; + else + _name = _itemDst.Value; + _typeName = TrimTypeName(_itemDst.Type); + if (_typeName == "") + { + if (Op == OP_MOV) + { + _line = _name + " := " + _imm + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_CMP) + { + CmpInfo.L = _name; + CmpInfo.O = CmpOp; + CmpInfo.R = _imm; + return; + } + if (Op == OP_ADD) + { + _line = _name + " := " + _name + " + " + _imm + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_SUB) + { + _line = _name + " := " + _name + " - " + _imm + ";"; + Env->AddToBody(_line); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } + _kind = GetTypeKind(_typeName, &_size); + if (Op == OP_MOV) + { + if (_kind == ikMethod) + { + if (IsValidImageAdr(DisInfo.Immediate)) + { + _ap = Adr2Pos(DisInfo.Immediate); + if (_ap >= 0) + { + _recN = GetInfoRec(DisInfo.Immediate); + if (_recN) + { + if (_recN->HasName()) + _line = _name + " := " + _recN->GetName() + ";"; + else + _line = _name + " := " + GetDefaultProcName(DisInfo.Immediate); + } + if (IsFlagSet(cfProcStart, _ap)) + { + _line = _name + " := " + GetDefaultProcName(DisInfo.Immediate); + } + } + else + { + _idx = BSSInfos->IndexOfName(Val2Str8(DisInfo.Immediate)); + if (_idx != -1) + { + _recN = (PInfoRec)BSSInfos->Objects[_idx]; + _line = _name + " := " + _recN->GetName() + ";"; + } + else + { + AddToBSSInfos(DisInfo.Immediate, MakeGvarName(DisInfo.Immediate), ""); + _line = _name + " := " + MakeGvarName(DisInfo.Immediate); + } + } + Env->AddToBody(_line); + return; + } + } + _line = _name + " := " + GetImmString(_typeName, DisInfo.Immediate) + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_CMP) + { + CmpInfo.L = _name; + CmpInfo.O = CmpOp; + CmpInfo.R = GetImmString(_typeName, DisInfo.Immediate); + return; + } + if (Op == OP_TEST) + { + if (_kind == ikSet) + { + CmpInfo.L = GetSetString(_typeName, (BYTE*)&DisInfo.Immediate); + CmpInfo.O = CmpOp + 12; + CmpInfo.R = _name; + return; + } + if (_kind == ikInteger) + { + CmpInfo.L = GetImmString(_typeName, DisInfo.Immediate); + CmpInfo.O = CmpOp; + CmpInfo.R = _name; + return; + } + _line = _name + " And " + GetImmString(_typeName, DisInfo.Immediate) + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || + Op == OP_AND || Op == OP_OR || Op == OP_XOR || Op == OP_SHL || Op == OP_SHR) + { + if (Op == OP_ADD) + _op = " + "; + else if (Op == OP_SUB) + _op = " - "; + else if (Op == OP_MUL || Op == OP_IMUL) + _op = " * "; + else if (Op == OP_AND) + _op = " And "; + else if (Op == OP_OR) + _op = " Or "; + else if (Op == OP_XOR) + _op = " Xor "; + else if (Op == OP_SHL) + _op = " Shl "; + else if (Op == OP_SHR) + _op = " Shr "; + else + _op = " ? "; + + _line = _name + " := " + _name + _op + GetImmString(_typeName, DisInfo.Immediate) + ";"; + Env->AddToBody(_line); + return; + } + + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateInstr2MemReg(DWORD curAdr, BYTE Op) +{ + bool _vmt; + BYTE _kind, _kind1, _kind2; + int _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _idx1, _classSize, _ap; + DWORD _adr; + ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; + ITEM _item, _item1, _item2; + PInfoRec _recN, _recN1; + PLOCALINFO _locInfo; + PFIELDINFO _fInfo; + String _name, _value, _typeName, _line, _comment, _imm, _iname, _fname, _key; + + _reg2Idx = DisInfo.OpRegIdx[1]; + GetRegItem(_reg2Idx, &_itemSrc); + + _value = GetDecompilerRegisterName(_reg2Idx); + if (_itemSrc.Value != "") _value = _itemSrc.Value; + + GetMemItem(curAdr, &_itemDst, Op); + _name = "?"; + if (_itemDst.Value != "") + { + _name = _itemDst.Value; + if (_itemDst.Name != "" && !SameText(_name, _itemDst.Name)) + _name += "{" + _itemDst.Name + "}"; + } + else if (_itemDst.Name != "") + { + _name = _itemDst.Name; + } + + if (_itemDst.Flags & IF_STACK_PTR) + { + if (Op == OP_MOV) + { + if (_itemSrc.Flags & IF_CALL_RESULT) + { + _itemSrc.Flags &= ~IF_CALL_RESULT; + _itemSrc.Value = Env->GetLvarName(_itemDst.IntValue, ""); + SetRegItem(_reg2Idx, &_itemSrc); + } + else + { + if (!(_itemSrc.Flags & IF_ARG)) + _itemSrc.Name = Env->GetLvarName(_itemDst.IntValue, ""); + if (_itemSrc.Value == "") + _itemSrc.Value = Env->GetLvarName(_itemDst.IntValue, ""); + } + + Env->Stack[_itemDst.IntValue] = _itemSrc; + _line = _name + " := " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_ADD) + { + _line = _name + " := " + _name + " + " + _value + ";"; + Env->AddToBody(_line); + Env->Stack[_itemDst.IntValue].Value = _name + " + " + _value; + return; + } + if (Op == OP_SUB) + { + _line = _name + " := " + _name + " - " + _value + ";"; + Env->AddToBody(_line); + Env->Stack[_itemDst.IntValue].Value = _name + " - " + _value; + return; + } + if (Op == OP_TEST) + { + CmpInfo.L = _name + " And " + _value; + CmpInfo.O = CmpOp; + CmpInfo.R = 0; + return; + } + if (Op == OP_XOR) + { + _line = _name + " := " + _name + " Xor " + _value + ";"; + Env->AddToBody(_line); + Env->Stack[_itemDst.IntValue].Value = _name + " Xor " + _value; + return; + } + if (Op == OP_BT) + { + CmpInfo.L = _name + "[" + _value + "]"; + CmpInfo.O = CmpOp; + CmpInfo.R = "True"; + return; + } + } + if (_itemDst.Flags & IF_INTVAL) + { + _offset = _itemDst.IntValue; + _ap = Adr2Pos(_offset); + _recN = GetInfoRec(_offset); + if (_recN) MakeGvar(_recN, _offset, curAdr); + if (_ap >= 0) + { + _adr = *(DWORD*)(Code + _ap); + //May be pointer to var + if (IsValidImageAdr(_adr)) + { + _recN = GetInfoRec(_adr); + if (_recN) + { + MakeGvar(_recN, _offset, _adr); + _line = "^"; + } + } + } + if (_recN) + { + if (_itemSrc.Type != "") _recN->type = _itemSrc.Type; + _name = _recN->GetName(); + } +/* + if (Op == OP_MOV) + { + _ap = Adr2Pos(_offset); _recN = GetInfoRec(_offset); + if (_ap >= 0) + { + _adr = *(DWORD*)(Code + _ap); + //May be pointer to var + if (IsValidImageAdr(_adr)) + { + _recN1 = GetInfoRec(_adr); + if (_recN1) + { + MakeGvar(_recN1, _offset, curAdr); + if (_itemSrc.Type != "") _recN1->type = _itemSrc.Type; + _line = "^" + _recN1->GetName() + " := " + _value + ";"; + Env->AddToBody(_line); + return; + } + } + } + if (_recN) + { + MakeGvar(_recN, _offset, curAdr); + if (_itemSrc.Type != "") _recN->type = _itemSrc.Type; + _line = _recN->GetName() + " := " + _value + ";"; + Env->AddToBody(_line); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); + } +*/ + } + if (Op == OP_MOV) + { + _line = _name + " := "; + _typeName = _itemDst.Type; + if (_typeName != "") + { + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikSet) + { + _line += GetSetString(_typeName, (BYTE*)&_itemSrc.IntValue) + ";"; + Env->AddToBody(_line); + return; + } + } + _line += GetDecompilerRegisterName(_reg2Idx) + ";"; + if (_value != "") _line += "//" + _value; + Env->AddToBody(_line); + return; + } + if (Op == OP_ADD) + { + _line = _name + " := " + _name + " + " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_SUB) + { + _line = _name + " := " + _name + " - " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_OR) + { + _line = _name + " := " + _name + " Or " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_XOR) + { + _line = _name + " := " + _name + " Xor " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_TEST) + { + CmpInfo.L = _name + " And " + _value; + CmpInfo.O = CmpOp; + CmpInfo.R = 0; + _line = _name + " := " + _name + " And " + _value + ";"; + Env->AddToBody(_line); + return; + } + if (Op == OP_BT) + { + CmpInfo.L = _value; + CmpInfo.O = 'Q'; + CmpInfo.R = _name; + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +//Simulate instruction with 2 operands +void __fastcall TDecompiler::SimulateInstr2(DWORD curAdr, BYTE Op) +{ + if (DisInfo.OpType[0] == otREG) + { + if (DisInfo.OpType[1] == otIMM) + { + SimulateInstr2RegImm(curAdr, Op); + return; + } + if (DisInfo.OpType[1] == otREG) + { + SimulateInstr2RegReg(curAdr, Op); + return; + } + if (DisInfo.OpType[1] == otMEM) + { + SimulateInstr2RegMem(curAdr, Op); + return; + } + } + if (DisInfo.OpType[0] == otMEM) + { + if (DisInfo.OpType[1] == otIMM) + { + SimulateInstr2MemImm(curAdr, Op); + return; + } + if (DisInfo.OpType[1] == otREG) + { + SimulateInstr2MemReg(curAdr, Op); + return; + } + } +} +//--------------------------------------------------------------------------- +//Simulate instruction with 3 operands +void __fastcall TDecompiler::SimulateInstr3(DWORD curAdr, BYTE Op) +{ + int _reg1Idx, _reg2Idx, _imm; + ITEM _itemDst, _itemSrc; + String _value, _line, _comment; + + _reg1Idx = DisInfo.OpRegIdx[0]; + _reg2Idx = DisInfo.OpRegIdx[1]; + _imm = DisInfo.Immediate; + + InitItem(&_itemDst); + _itemDst.Type = "Integer"; + + if (Op == OP_IMUL) + { + //mul reg, reg, imm + if (DisInfo.OpType[1] == otREG) + { + _value = String(_imm) + " * " + GetDecompilerRegisterName(_reg2Idx); + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _value; + GetRegItem(_reg2Idx, &_itemSrc); + _comment = String(_imm) + " * " + GetString(&_itemSrc, PRECEDENCE_MULT); + _itemDst.Precedence = PRECEDENCE_MULT; + _itemDst.Value = _comment; + SetRegItem(_reg1Idx, &_itemDst); + Env->AddToBody(_line + ";//" + _comment); + return; + } + //mul reg, [Mem], imm + if (DisInfo.OpType[1] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, Op); + _value = String(_imm) + " * " + _itemSrc.Name; + _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _value; + _comment = String(_imm) + " * " + GetString(&_itemSrc, PRECEDENCE_MULT); + _itemDst.Precedence = PRECEDENCE_MULT; + _itemDst.Value = _comment; + SetRegItem(_reg1Idx, &_itemDst); + Env->AddToBody(_line + ";//" + _comment); + return; + } + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +DWORD __fastcall TDecompiler::DecompileTry(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo) +{ + BYTE op; + int pos, tpos, pos1, instrLen, skipNum; + DWORD startTryAdr, endTryAdr, startFinallyAdr, endFinallyAdr, endExceptAdr, adr, endAdr, hAdr; + PInfoRec recN; + ITEM item; + TDecompiler *de; + + skipNum = IsTryBegin(fromAdr, &startTryAdr) + IsTryBegin0(fromAdr, &startTryAdr); + adr = startTryAdr; pos = Adr2Pos(adr); + + if (IsFlagSet(cfFinally, pos)) + { + //jmp @HandleFinally + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, 0, 0); + adr += instrLen; pos += instrLen; + //jmp @2 + Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + startFinallyAdr = DisInfo.Immediate; + //Get prev push + pos1 = GetNearestUpInstruction(Adr2Pos(DisInfo.Immediate)); + Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &DisInfo, 0); + endFinallyAdr = DisInfo.Immediate; + //Find flag cfFinally + while (1) + { + pos1--; + if (IsFlagSet(cfFinally, pos1)) break; + } + if (pos1) endTryAdr = Pos2Adr(pos1); + if (!endTryAdr) + { + Env->ErrAdr = fromAdr; + throw Exception("Invalid end address of try section"); + } + //Decompile try + Env->AddToBody("try"); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(endTryAdr); + try + { + endAdr = de->Decompile(fromAdr + skipNum, flags, loopInfo); + } + catch(Exception &exception) + { + delete de; + throw Exception("Try->" + exception.Message); + } + delete de; + + Env->AddToBody("finally"); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(endFinallyAdr); + try + { + endAdr = de->Decompile(startFinallyAdr, CF_FINALLY, loopInfo); + } + catch(Exception &exception) + { + delete de; + throw Exception("Try->" + exception.Message); + } + Env->AddToBody("end"); + delete de; + return endAdr; + } + else if (IsFlagSet(cfExcept, pos)) + { + //Prev jmp + pos1 = GetNearestUpInstruction(pos); + Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &DisInfo, 0); + endExceptAdr = DisInfo.Immediate; + //Next + pos += Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &DisInfo, 0); + //Find prev flag cfExcept + while (1) + { + if (IsFlagSet(cfExcept, pos1)) break; + pos1--; + } + if (pos1) endTryAdr = Pos2Adr(pos1); + if (!endTryAdr) + { + Env->ErrAdr = fromAdr; + throw Exception("Invalid end address of try section"); + } + //Decompile try + Env->AddToBody("try"); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(endTryAdr); + try + { + endAdr = de->Decompile(fromAdr + skipNum, 0, loopInfo); + } + catch(Exception &exception) + { + delete de; + throw Exception("Try->" + exception.Message); + } + delete de; + //on except + if (IsFlagSet(cfETable, pos)) + { + Env->AddToBody("except"); + int num = *((DWORD*)(Code + pos)); pos += 4; + //Table pos + tpos = pos; + for (int n = 0; n < num; n++) + { + adr = *((DWORD*)(Code + pos)); pos += 4; + if (IsValidCodeAdr(adr)) + { + recN = GetInfoRec(adr); + InitItem(&item); + item.Value = "E"; + item.Type = recN->GetName(); + SetRegItem(16, &item); //eax -> exception info + Env->AddToBody("on E:" + recN->GetName() + " do"); + } + else + { + Env->AddToBody("else"); + } + hAdr = *((DWORD*)(Code + pos)); pos += 4; + if (IsValidCodeAdr(hAdr)) + { + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); pos1 = tpos; + for (int m = 0; m < num; m++) + { + pos1 += 4; + adr = *((DWORD*)(Code + pos1)); pos1 += 4; + de->SetStop(adr); + } + de->ClearStop(hAdr); + de->SetStop(endExceptAdr); + try + { + Env->AddToBody("begin"); + endAdr = de->Decompile(hAdr, 0, loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("Try->" + exception.Message); + } + delete de; + } + } + Env->AddToBody("end"); + } + //except + else + { + Env->AddToBody("except"); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(endExceptAdr); + try + { + endAdr = de->Decompile(Pos2Adr(pos), CF_EXCEPT, loopInfo); + } + catch(Exception &exception) + { + delete de; + throw Exception("Try->" + exception.Message); + } + Env->AddToBody("end"); + delete de; + } + return endAdr;//endExceptAdr; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::MarkCaseEnum(DWORD fromAdr) +{ + BYTE b; + DWORD adr = fromAdr, jAdr; + int n, pos = Adr2Pos(fromAdr), cTblPos, jTblPos; + + //cmp reg, Imm + //Imm - + int instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + int caseNum = DisInfo.Immediate + 1; + pos += instrLen; + adr += instrLen; + //ja EndOfCaseAdr + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + DWORD endOfCaseAdr = DisInfo.Immediate; + + pos += instrLen; + adr += instrLen; + //mov??? + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + BYTE op = Disasm.GetOp(DisInfo.Mnem); + DWORD cTblAdr = 0, jTblAdr = 0; + if (op == OP_MOV) + { + cTblAdr = DisInfo.Offset; + pos += instrLen; + adr += instrLen; + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + } + jTblAdr = DisInfo.Offset; + int maxN = 0; + if (cTblAdr) + { + cTblPos = Adr2Pos(cTblAdr); + int cNum = jTblAdr - cTblAdr; + for (n = 0; n < cNum; n++) + { + b = *(Code + cTblPos); + if (b > maxN) maxN = b; + cTblPos++; + } + jTblPos = Adr2Pos(jTblAdr); + for (n = 0; n <= maxN; n++) + { + jAdr = *((DWORD*)(Code + jTblPos)); + SetStop(jAdr); + jTblPos += 4; + } + } + else + { + jTblPos = Adr2Pos(jTblAdr); + for (n = 0; n < caseNum; n++) + { + if (IsFlagSet(cfCode | cfLoc, jTblPos)) break; + jAdr = *((DWORD*)(Code + jTblPos)); + SetStop(jAdr); + jTblPos += 4; + } + } +} +//--------------------------------------------------------------------------- +DWORD __fastcall TDecompiler::DecompileCaseEnum(DWORD fromAdr, int N, PLoopInfo loopInfo) +{ + bool skip; + BYTE b; + DWORD adr = fromAdr, jAdr, jAdr1, _adr, _endAdr = 0; + int n, m, pos = Adr2Pos(fromAdr), cTblPos, cTblPos1, jTblPos, jTblPos1; + ITEM item, item1; + String line = ""; + TDecompiler *de; + + //cmp reg, Imm + //Imm - + int instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + int caseNum = DisInfo.Immediate + 1; + pos += instrLen; + adr += instrLen; + //ja EndOfCaseAdr + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + DWORD endOfCaseAdr = DisInfo.Immediate; + + pos += instrLen; + adr += instrLen; + //mov??? + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + BYTE op = Disasm.GetOp(DisInfo.Mnem); + DWORD cTblAdr = 0, jTblAdr = 0; + if (op == OP_MOV) + { + cTblAdr = DisInfo.Offset; + pos += instrLen; + adr += instrLen; + instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); + } + jTblAdr = DisInfo.Offset; + int maxN = 0; + if (cTblAdr) + { + cTblPos = Adr2Pos(cTblAdr); + int cNum = jTblAdr - cTblAdr; + for (n = 0; n < cNum; n++) + { + b = *(Code + cTblPos); + if (b > maxN) maxN = b; + cTblPos++; + } + jTblPos = Adr2Pos(jTblAdr); + for (m = 0; m <= maxN; m++) + { + line = ""; + skip = false; + cTblPos = Adr2Pos(cTblAdr); + for (n = 0; n < cNum; n++) + { + b = *(Code + cTblPos); + jAdr = *((DWORD*)(Code + jTblPos)); + if (b == m) + { + if (jAdr == endOfCaseAdr) + { + skip = true; + break; + } + if (line != "") line += ","; + line += String(n + N); + } + cTblPos++; + } + if (!skip) + { + Env->AddToBody(line + ":"); + Env->SaveContext(endOfCaseAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(endOfCaseAdr); + de->MarkCaseEnum(fromAdr); + de->ClearStop(jAdr); + + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(jAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("CaseEnum->" + exception.Message); + } + Env->RestoreContext(endOfCaseAdr); + delete de; + } + jTblPos += 4; + } + return _endAdr;//endOfCaseAdr; + } + jTblPos = Adr2Pos(jTblAdr); + for (n = 0; n < caseNum; n++) + { + if (IsFlagSet(cfCode | cfLoc, jTblPos)) break; + jAdr = *((DWORD*)(Code + jTblPos)); + if (jAdr != endOfCaseAdr) + { + skip = false; + //If case already decompiled? + jTblPos1 = Adr2Pos(jTblAdr); + for (m = 0; m < n; m++) + { + jAdr1 = *((DWORD*)(Code + jTblPos1)); + if (jAdr1 == jAdr) + { + skip = true; + break; + } + jTblPos1 += 4; + } + + if (!skip) + { + line = ""; + jTblPos1 = Adr2Pos(jTblAdr); + for (m = 0; m < caseNum; m++) + { + if (IsFlagSet(cfCode | cfLoc, jTblPos1)) break; + jAdr1 = *((DWORD*)(Code + jTblPos1)); + if (jAdr1 == jAdr) + { + if (line != "") line += ","; + line += String(m + N); + } + jTblPos1 += 4; + } + Env->AddToBody(line + ":"); + Env->SaveContext(endOfCaseAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(endOfCaseAdr); + de->MarkCaseEnum(fromAdr); + de->ClearStop(jAdr); + + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(jAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("CaseEnum->" + exception.Message); + } + Env->RestoreContext(endOfCaseAdr); + delete de; + } + } + jTblPos += 4; + } + return _endAdr;//endOfCaseAdr; +} +//--------------------------------------------------------------------------- +String __fastcall TDecompiler::GetSysCallAlias(String AName) +{ + if (SameText(AName, "@Assign") || + SameText(AName, "@AssignText")) return "AssignFile"; + if (SameText(AName, "@Append")) return "Append"; + if (SameText(AName, "@Assert")) return "Assert"; + if (SameText(AName, "@BlockRead")) return "Read"; + if (SameText(AName, "@BlockWrite")) return "Write"; + if (SameText(AName, "@ChDir")) return "ChDir"; + if (SameText(AName, "@Close")) return "CloseFile"; + if (SameText(AName, "@DynArrayHigh")) return "High"; + if (SameText(AName, "@EofText")) return "Eof"; + if (SameText(AName, "@FillChar")) return "FillChar"; + if (SameText(AName, "@Flush")) return "Flush"; + if (SameText(AName, "@Copy") || + SameText(AName, "@LStrCopy") || + SameText(AName, "@WStrCopy") || + SameText(AName, "@UStrCopy")) return "Copy"; + if (SameText(AName, "@LStrDelete") || + SameText(AName, "@UStrDelete")) return "Delete"; + if (SameText(AName, "@LStrFromPCharLen")) return "SetString"; + if (SameText(AName, "@LStrInsert")) return "Insert"; + if (SameText(AName, "@PCharLen") || + SameText(AName, "@LStrLen") || + SameText(AName, "@WStrLen") || + SameText(AName, "@UStrLen")) return "Length"; + if (SameText(AName, "@LStrOfChar")) return "StringOfChar"; + if (SameText(AName, "@Pos") || + SameText(AName, "@LStrPos") || + SameText(AName, "@WStrPos") || + SameText(AName, "@UStrPos")) return "Pos"; + if (SameText(AName, "@LStrSetLength") || + SameText(AName, "@UStrSetLength")) return "SetLength"; + if (SameText(AName, "@MkDir")) return "MkDir"; + if (SameText(AName, "@New")) return "New"; + if (SameText(AName, "@RaiseAgain")) return "Raise"; + if (SameText(AName, "@RandInt")) return "Random"; + if (SameText(AName, "@ReadLn")) return "ReadLn"; + if (SameText(AName, "@ReadLong") || + SameText(AName, "@ReadLString") || + SameText(AName, "@ReadRec") || + SameText(AName, "@ReadUString")) return "Read"; + if (SameText(AName, "@ReallocMem")) return "ReallocMem"; + if (SameText(AName, "@ResetFile") || + SameText(AName, "@ResetText")) return "Reset"; + if (SameText(AName, "@ValLong") || + SameText(AName, "@ValInt64")) return "Val"; + if (SameText(AName, "@WriteLn")) return "WriteLn"; + return ""; +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompiler::SimulateSysCall(String name, DWORD procAdr, int instrLen) +{ + int _cnt, _esp, _cmpRes, _size; + DWORD _adr; + ITEM _item, _item1, _item2, _item3, _item4; + PInfoRec _recN; + String _line, _value, _value1, _value2, _typeName, _varName1, _varName2, _op; + __int64 _int64Val; + + if (SameText(name, "@AsClass")) + { + //type of edx -> type of eax + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + _item1.Value = _item2.Type + "(" + _item1.Value + ")"; + _item1.Type = _item2.Type; + SetRegItem(16, &_item1); + return false; + } + if (SameText(name, "@IsClass")) + { + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + _adr = _item2.IntValue; + if (!IsValidImageAdr(_adr)) + { + throw Exception("Invalid address"); + } + _recN = GetInfoRec(_adr); + InitItem(&_item); + _item.Value = "(" + _item1.Value + " is " + _recN->GetName() + ")"; + _item.Type = "Boolean"; + SetRegItem(16, &_item); + return false; + } + if (SameText(name, "@CopyRecord")) + { + //dest:Pointer + GetRegItem(16, &_item1); + //source:Pointer + GetRegItem(18, &_item2); + //typeInfo:Pointer + GetRegItem(17, &_item3); + _recN = GetInfoRec(_item3.IntValue); + _typeName = _recN->GetName(); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); + _item1 = Env->Stack[_item1.IntValue]; + } + Env->Stack[_item1.IntValue].Type = _typeName; + + _line = _item1.Value + " := " + _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@DynArrayAsg")) + { + //eax - dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + if (Env->Stack[_item1.IntValue].Value == "") Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, "array of"); + _item1 = Env->Stack[_item1.IntValue]; + } + //edx - src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + if (Env->Stack[_item2.IntValue].Value == "") Env->Stack[_item2.IntValue].Value = Env->GetLvarName(_item2.IntValue, "array of"); + _item2 = Env->Stack[_item2.IntValue]; + } + _line = _item1.Value + " := " + _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@DynArrayClear")) + { + //eax - var + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + if (Env->Stack[_item1.IntValue].Value == "") Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, "array of"); + _item1 = Env->Stack[_item1.IntValue]; + } + _line = _item1.Value + " := Nil;"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@DynArrayLength")) + { + //eax - ptr + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + if (Env->Stack[_item1.IntValue].Value == "") Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, "array of"); + _item1 = Env->Stack[_item1.IntValue]; + } + _value = "Length(" + _item1.Value + ")"; + _line = "EAX := " + _value; + Env->AddToBody(_line); + InitItem(&_item); + _item.Flags |= IF_CALL_RESULT; + _item.Value = _value; + _item.Type = "Integer"; + SetRegItem(16, &_item); + return false; + } + if (SameText(name, "@DynArraySetLength"))//stdcall + { + _line = "SetLength("; + //eax - dst + GetRegItem(16, &_item1); _item = _item1; + //edx - type of DynArray + GetRegItem(18, &_item2); + _typeName = GetTypeName(_item2.IntValue); + if (_item1.Flags & IF_STACK_PTR) + { + if (Env->Stack[_item1.IntValue].Value == "") Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); + _item = Env->Stack[_item1.IntValue]; + Env->Stack[_item1.IntValue].Type = _typeName; + _line += _item.Value; + } + else if (_item1.Flags & IF_INTVAL) + { + _line += MakeGvarName(_item1.IntValue); + } + else + { + _line += _item.Value; + } + //ecx - dims cnt + GetRegItem(17, &_item3); _cnt = _item3.IntValue; + _esp = _ESP_; + for (int n = 0; n < _cnt; n++) + { + _line += ", "; + _item = Env->Stack[_esp]; + if (_item.Flags & IF_INTVAL) + _line += String(_item.IntValue); + else + _line += _item.Value; + _esp += 4; + } + _line += ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@FreeMem")) + { + _line = "FreeMem("; + GetRegItem(16, &_item); + if (_item.Value != "") + _line += _item.Value; + else + _line += "EAX"; + _line += ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@GetMem")) + { + _value = "GetMem("; + //eax-Bytes + GetRegItem(16, &_item); + if (_item.Flags & IF_INTVAL) + _value += String(_item.IntValue); + else + _value += _item.Value; + _value += ")"; + _line = _value + ";"; + Env->AddToBody(_line); + + _typeName = ManualInput(CurProcAdr, procAdr, "Define type of function GetMem", "Type:"); + if (_typeName == "") + { + Env->ErrAdr = procAdr; + throw Exception("Bye!"); + } + + InitItem(&_item); + _item.Flags |= IF_CALL_RESULT; + _item.Value = _value; + _item.Type = _typeName; + SetRegItem(16, &_item); + return false; + } + if (SameText(name, "@Halt0")) + { + //_line = "Exit;"; + //Env->AddToBody(_line); + return false; + } + if (SameText(name, "@InitializeRecord") || + SameText(name, "@FinalizeRecord") || + SameText(name, "@AddRefRecord")) + { + //eax - dst + GetRegItem(16, &_item1); + //edx - TypeInfo + GetRegItem(18, &_item2); + if (_item1.Flags & IF_STACK_PTR) + { + _typeName = GetTypeName(_item2.IntValue); + _size = GetRecordSize(_typeName); + for (int r = 0; r < _size; r++) + { + if (_item1.IntValue + r >= Env->StackSize) + { + Env->ErrAdr = procAdr; + throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); + } + _item = Env->Stack[_item1.IntValue + r]; + _item.Flags = IF_FIELD; + _item.Offset = r; + _item.Type = ""; + if (r == 0) _item.Type = _typeName; + Env->Stack[_item1.IntValue + r] = _item; + } + if (Env->Stack[_item1.IntValue].Value == "") Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); + Env->Stack[_item1.IntValue].Type = _typeName; + } + return false; + } + if (SameText(name, "@InitializeArray") || + SameText(name, "@FinalizeArray")) + { + //eax - dst + GetRegItem(16, &_item1); _item = _item1; + //edx - type of DynArray + GetRegItem(18, &_item2); + //ecx - dims cnt + GetRegItem(17, &_item3); _cnt = _item3.IntValue; + _typeName = "array [1.." + String(_cnt) + "] of " + GetTypeName(_item2.IntValue); + if (_item1.Flags & IF_STACK_PTR) + { + if (Env->Stack[_item1.IntValue].Value == "") + Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); + _item = Env->Stack[_item1.IntValue]; + } + Env->Stack[_item1.IntValue].Type = _typeName; + return false; + } + if (SameText(name, "@IntfCast")) + { + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + _line = "(" + _item1.Value + " as " + _item2.Value1 + ")"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@IntfClear")) + { + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "IInterface"; + + _line = _item1.Value + " := Nil;"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@IntfCopy")) + { + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + _line = _item1.Value + " := " + _item2.Value1; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrAsg") || + SameText(name, "@LStrLAsg") || + SameText(name, "@WStrAsg") || + SameText(name, "@WStrLAsg") || + SameText(name, "@UStrAsg") || + SameText(name, "@UStrLAsg")) + { + //eax - dst + GetRegItem(16, &_item1); + //edx - src + GetRegItem(18, &_item2); + _line = GetStringArgument(&_item1) + " := " + GetStringArgument(&_item2) + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrCat") || + SameText(name, "@WStrCat") || + SameText(name, "@UStrCat")) + { + //eax - dst + GetRegItem(16, &_item); + _line = GetStringArgument(&_item) + " := " + GetStringArgument(&_item) + " + "; + //edx - src + GetRegItem(18, &_item); + _line += GetStringArgument(&_item) + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrCat3") || + SameText(name, "@WStrCat3") || + SameText(name, "@UStrCat3")) + { + //eax - dst + GetRegItem(16, &_item); + _line = GetStringArgument(&_item) + " := "; + //edx - str1 + GetRegItem(18, &_item); + _line += GetStringArgument(&_item) + " + "; + //ecx - str2 + GetRegItem(17, &_item); + _line += GetStringArgument(&_item) + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrCatN") || + SameText(name, "@WStrCatN") || + SameText(name, "@UStrCatN")) + { + //eax - dst + GetRegItem(16, &_item); + _line = GetStringArgument(&_item) + " := "; + if (_item.Flags & IF_STACK_PTR) + { + Env->Stack[_item.IntValue].Flags = 0; + Env->Stack[_item.IntValue].Value = Env->GetLvarName(_item.IntValue, "String"); + if (name[2] == 'L') + Env->Stack[_item.IntValue].Type = "AnsiString"; + else if (name[2] == 'W') + Env->Stack[_item.IntValue].Type = "WideString"; + else + Env->Stack[_item.IntValue].Type = "UnicodeString"; + } + //edx - argCnt + GetRegItem(18, &_item2); _cnt = _item2.IntValue; + _ESP_ += 4*_cnt; _esp = _ESP_; + for (int n = 0; n < _cnt; n++) + { + if (n) _line += " + "; + _esp -= 4; + _item = Env->Stack[_esp]; + _line += GetStringArgument(&_item); + } + _line += ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrClr") || + SameText(name, "@WStrClr") || + SameText(name, "@UStrClr")) + { + GetRegItem(16, &_item); + _line = GetStringArgument(&_item) + " := '';"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@AStrCmp") || + SameText(name, "@LStrCmp") || + SameText(name, "@WStrCmp") || + SameText(name, "@UStrCmp") || + SameText(name, "@UStrEqual")) + { + GetCmpInfo(procAdr + instrLen); + CmpInfo.O = 'F';//By default (<>) + + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) _item1 = Env->Stack[_item1.IntValue]; + CmpInfo.L = _item1.Value; + + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + _item2 = Env->Stack[_item2.IntValue]; + CmpInfo.R = _item2.Value; + } + else if (_item2.Flags & IF_INTVAL) + { + if (!_item2.IntValue) + CmpInfo.R = "''"; + else + { + _recN = GetInfoRec(_item2.IntValue); + if (_recN) + CmpInfo.R = _recN->GetName(); + else +//Fix it!!! +//Add analyze of String type + CmpInfo.R = TransformString(Code + Adr2Pos(_item2.IntValue), -1); + } + } + else + { + CmpInfo.R = _item2.Value; + } + return true; + } + if (SameText(name, "@LStrFromArray") || + SameText(name, "@LStrFromChar") || + SameText(name, "@LStrFromPChar") || + SameText(name, "@LStrFromString") || + SameText(name, "@LStrFromWStr") || + SameText(name, "@LStrFromUStr")) + { + //eax - dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "String"; + } + //edx - src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + if (name[10] == 'A') + _typeName = "PAnsiChar"; + else if (name[10] == 'C') + _typeName = "Char"; + else if (name[10] == 'P') + _typeName = "PChar"; + else if (name[10] == 'S') + _typeName = "ShortString"; + else if (name[10] == 'W') + _typeName = "WideString"; + else if (name[10] == 'U') + _typeName = "UnicodeString"; + + Env->Stack[_item2.IntValue].Type = _typeName; + } + _line = _item1.Value + " := " + _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrToPChar")) + { + //eax - src + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "String"; + _item1.Value = "PChar(" + _item1.Value + ")"; + SetRegItem(16, &_item1); + _line = "EAX := " + _item1.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@LStrToString")) + { + //eax - dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_INTVAL) + { + _line = MakeGvarName(_item1.IntValue); + } + else if (_item1.Flags & IF_STACK_PTR) + { + _line = _item1.Value; + Env->Stack[_item1.IntValue].Type = "ShortString"; + } + //edx - src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + Env->Stack[_item2.IntValue].Type = "String"; + _line += " := " + _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@PStrNCat") || + SameText(name, "@PStrCpy") || + SameText(name, "@PStrNCpy")) + { + //eax - dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "ShortString"; + //edx - src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + Env->Stack[_item2.IntValue].Type = "ShortString"; + _line = _item1.Value + " := "; + if (SameText(name, "@PStrNCat")) _line += _item1.Value + " + "; + _line += _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@RaiseExcept")) + { + //eax - Exception + GetRegItem(16, &_item1); + _line = "raise " + _item1.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@RewritFile") || + SameText(name, "@RewritText")) + { + //File + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) _item1 = Env->Stack[_item1.IntValue]; + _line = "Rewrite(" + ExtractClassName(_item1.Value) + ");"; + Env->AddToBody(_line); + return false; + } + + if (SameText(name, "@Sin") || + SameText(name, "@Cos") || + SameText(name, "@Exp") || + SameText(name, "@Int")) + { + _value = name.SubString(2, 5); + InitItem(&_item1); + _item1.Value = _value + "(" + FGet(0)->Value + ")"; + _item1.Type = "Extended"; + FSet(0, &_item1); + return false; + } + if (SameText(name, "@Trunc") || + SameText(name, "@Round")) + { + _value = name.SubString(2, 5) + "(" + FGet(0)->Value + ")"; + InitItem(&_item); + _item.Value = _value; + _item.Type = "Int64"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "//EAX := " + _value + ";"; + Env->AddToBody(_line); + FPop(); + return false; + } + if (SameText(name.SubString(1, name.Length() - 1), "@UniqueString")) + { + GetRegItem(16, &_item1); + InitItem(&_item); + _item.Value = "EAX"; + _item.Type = "String"; + SetRegItem(16, &_item); + if (_item1.Flags & IF_STACK_PTR) + { + _value = "UniqueString(" + Env->Stack[_item1.IntValue].Value + ")"; + Env->Stack[_item1.IntValue].Type = "String"; + _line = "//EAX := " + _value; + Env->AddToBody(_line); + return false; + } + _value = "UniqueString(" + _item1.Value + ")"; + _line = "//EAX := " + _value; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrFromChar") || + SameText(name, "@UStrFromWChar")) + { + //eax-Dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + } + //edx-Src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + if (name[11] == 'C') + Env->Stack[_item2.IntValue].Type = "Char"; + else + Env->Stack[_item2.IntValue].Type = "WideChar"; + } + _line = _item1.Value + " := " + _item2.Value; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrFromLStr")) + { + //eax-Dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + } + //edx-Src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + Env->Stack[_item2.IntValue].Type = "AnsiString"; + } + _line = _item1.Value + " := " + _item2.Value; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrFromString")) + { + //eax - dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + } + //edx - src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + Env->Stack[_item2.IntValue].Type = "ShortString"; + } + _line = _item1.Value + " := " + _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrFromWStr")) + { + //eax-Dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + } + //edx-Src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + Env->Stack[_item2.IntValue].Type = "WideString"; + } + _line = _item1.Value + " := " + _item2.Value; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrFromPWChar")) + { + //eax - Dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + } + //edx-Src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + Env->Stack[_item2.IntValue].Type = "PWideChar"; + } + _line = _item1.Value + " := " + _item2.Value; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@WStrToPWChar")) + { + //eax - src + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "WideString"; + } + _item1.Value = "PWideChar(" + _item1.Value + ")"; + _item1.Type = "PWideChar"; + SetRegItem(16, &_item1); + _line = "EAX := " + _item1.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrToPWChar")) + { + //eax - src + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + } + _item1.Value = "PWideChar(" + _item1.Value + ")"; + _item1.Type = "PWideChar"; + SetRegItem(16, &_item1); + _line = "EAX := " + _item1.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@UStrToString")) + { + //eax - dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "UnicodeString"; + //edx - src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + Env->Stack[_item2.IntValue].Type = "String"; + _line = _item1.Value + " := " + _item2.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarClear")) + { + GetRegItem(16, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + _line = _varName1 + " := 0;"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarAdd") || + SameText(name, "@VarSub") || + SameText(name, "@VarMul") || + SameText(name, "@VarDiv") || + SameText(name, "@VarMod") || + SameText(name, "@VarAnd") || + SameText(name, "@VarOr") || + SameText(name, "@VarXor") || + SameText(name, "@VarShl") || + SameText(name, "@VarShr") || + SameText(name, "@VarRDiv")) + { + _op = name.SubString(5, name.Length()); + + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + if (_item2.Flags & IF_STACK_PTR) + _varName2 = Env->GetLvarName(_item2.IntValue, "Variant"); + + _line = _varName1 + " := " + _varName1 + " " + _op + " " + _varName2 + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarNeg") || + SameText(name, "@VarNot")) + { + _op = name.SubString(5, name.Length()); + GetRegItem(16, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + _line = _varName1 + " := " + _op + " " + _varName1 + ";"; + Env->AddToBody(_line); + return false; + } + + if (SameText(name.SubString(1, 7), "@VarCmp")) + { + GetCmpInfo(procAdr + instrLen); + if (name[8] == 'E' && name[9] == 'Q') + CmpInfo.O = 'E';//JZ + else if (name[8] == 'N' && name[9] == 'E') + CmpInfo.O = 'F';//JNZ + else if (name[8] == 'L') + { + if (name[9] == 'E') + CmpInfo.O = 'O';//JLE + else if (name[9] == 'T') + CmpInfo.O = 'M';//JL + } + else if (name[8] == 'G') + { + if (name[9] == 'E') + CmpInfo.O = 'N';//JGE + else if (name[9] == 'T') + CmpInfo.O = 'P';//JG + } + + GetRegItem(16, &_item1);//eax - Left argument + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + CmpInfo.L = _varName1; + + GetRegItem(18, &_item2);//edx - Right argument + _varName2 = _item2.Name; + if (_item2.Flags & IF_STACK_PTR) + _varName2 = Env->GetLvarName(_item2.IntValue, "Variant"); + + CmpInfo.R = _varName2; + return true; + } + //Cast to Variant + if (SameText(name, "@VarFromBool") || + SameText(name, "@VarFromInt") || + SameText(name, "@VarFromPStr") || + SameText(name, "@VarFromLStr") || + SameText(name, "@VarFromWStr") || + SameText(name, "@VarFromUStr") || + SameText(name, "@VarFromDisp")) + { + GetRegItem(16, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + _line = _varName1 + " := Variant("; + GetRegItem(18, &_item2); + if (_item2.Flags & IF_INTVAL) + _line += _item2.IntValue; + else + _line += _item2.Value; + _line += ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarFromTDateTime") || + SameText(name, "@VarFromCurr")) + { + GetRegItem(16, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + _line = _varName1 + " := Variant(" + FPop()->Value + ")";//FGet(0) + Env->AddToBody(_line); + //FPop(); + return false; + } + if (SameText(name, "@VarFromReal")) + { + GetRegItem(16, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + _line = _varName1 + " := Variant(" + FPop()->Value + ")";//??? + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarToInt")) + { + //eax=Variant, return Integer + GetRegItem(16, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + InitItem(&_item); + _item.Value = "Integer(" + _varName1 + ")"; + SetRegItem(16, &_item); + _line = "EAX := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarToInteger")) + { + //edx=Variant, eax=Integer + GetRegItem(18, &_item1); + _varName1 = _item1.Name; + if (_item1.Flags & IF_STACK_PTR) + _varName1 = Env->GetLvarName(_item1.IntValue, "Variant"); + + GetRegItem(16, &_item2); + _varName2 = _item2.Name; + if (_item2.Flags & IF_STACK_PTR) + _varName2 = Env->GetLvarName(_item2.IntValue, "Variant"); + + InitItem(&_item); + _item.Value = "Integer(" + _varName1 + ")"; + SetRegItem(16, &_item); + _line = _varName2 + " := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarToLStr")) + { + //edx=Variant, eax=String + GetRegItem(18, &_item1); + GetRegItem(16, &_item2); + + if (_item2.Flags & IF_INTVAL)//!!!Use it for other cases!!! + { + _line = MakeGvarName(_item2.IntValue); + } + else if (_item2.Flags & IF_STACK_PTR) + { + _line = Env->GetLvarName(_item2.IntValue, "String"); + Env->Stack[_item2.IntValue].Type = "String"; + } + else + { + _line = _item2.Value; + } + + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "Variant"; + InitItem(&_item); + _item.Value = "String(" + _item1.Value + ")"; + SetRegItem(16, &_item); + _line += " := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarToWStr")) + { + //edx=Variant, eax=String + GetRegItem(18, &_item1); + GetRegItem(16, &_item2); + + if (_item2.Flags & IF_INTVAL)//!!!Use it for other cases!!! + { + _line = MakeGvarName(_item2.IntValue); + } + else if (_item2.Flags & IF_STACK_PTR) + { + _line = Env->GetLvarName(_item2.IntValue, "WideString"); + Env->Stack[_item2.IntValue].Type = "WideString"; + } + else + { + _line = _item2.Value; + } + + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "Variant"; + InitItem(&_item); + _item.Value = "WideString(" + _item1.Value + ")"; + SetRegItem(16, &_item); + _line += " := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@VarToReal")) + { + //eax=Variant + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + Env->Stack[_item1.IntValue].Type = "Variant"; + InitItem(&_item); + _item.Value = "Real(" + _item1.Value + ")"; + _item.Type = "Extended"; + FSet(0, &_item); + return false; + } + if (SameText(name, "@Write0Ext")) + { + //File + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) _item1 = Env->Stack[_item1.IntValue]; + //Value (Extended) + GetFloatItemFromStack(_ESP_, &_item2, FT_EXTENDED); _ESP_ += 12; + _line = "Write(" + ExtractClassName(_item1.Value) + ", " + _item2.Value + ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@Str0Ext")) + { + //Value (Extended) + GetFloatItemFromStack(_ESP_, &_item1, FT_EXTENDED); _ESP_ += 12; + //Destination - eax + GetRegItem(16, &_item2); + _line = "Str(" + _item1.Value + ", " + _item2.Value + ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@Str1Ext")) + { + //Value (Extended) + GetFloatItemFromStack(_ESP_, &_item1, FT_EXTENDED); _ESP_ += 12; + //Width - eax + GetRegItem(16, &_item2); + //Destination - edx + GetRegItem(18, &_item3); + _line = "Str(" + _item1.Value + ":" + String(_item2.IntValue) + ", " + _item3.Value + ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@Str2Ext")) + { + //Value (Extended) + GetFloatItemFromStack(_ESP_, &_item1, FT_EXTENDED); _ESP_ += 12; + //Width - eax + GetRegItem(16, &_item2); + //Precision - edx + GetRegItem(18, &_item3); + //Destination - ecx + GetRegItem(17, &_item4); + _line = "Str(" + _item1.Value + ":" + String(_item2.IntValue) + ":" + String(_item3.IntValue) + ", " + _item4.Value + ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@Write2Ext")) + { + //File + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) _item1 = Env->Stack[_item1.IntValue]; + //Value (Extended) + GetFloatItemFromStack(_ESP_, &_item2, FT_EXTENDED); _ESP_ += 12; + //edx + GetRegItem(18, &_item3); + //ecx + GetRegItem(17, &_item4); + _line = "Write(" + ExtractClassName(_item1.Value) + ", " + _item2.Value + ":" + String(_item3.IntValue) + ":" + String(_item4.IntValue) + ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@Write0Char") || + SameText(name, "@Write0WChar") || + SameText(name, "@WriteLong") || + SameText(name, "@Write0Long")) + { + //File + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) _item1 = Env->Stack[_item1.IntValue]; + _line = "Write(" + ExtractClassName(_item1.Value) + ", "; + //edx + GetRegItem(18, &_item2); + if (_item2.Flags & IF_INTVAL) + _line += GetImmString(_item2.IntValue); + else + _line += _item2.Value; + _line += ");"; + Env->AddToBody(_line); + return false; + } + if (SameText(name, "@Write0LString") || + SameText(name, "@Write0UString")) + { + //File + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) _item1 = Env->Stack[_item1.IntValue]; + //edx + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) _item2 = Env->Stack[_item2.IntValue]; + _line = "Write(" + ExtractClassName(_item1.Value) + ", " + _item2.Value + ");"; + Env->AddToBody(_line); + return false; + } + + if (SameText(name, "@WStrFromUStr") || + SameText(name, "@WStrFromLStr")) + { + //eax-Dst + GetRegItem(16, &_item1); + if (_item1.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_item1.IntValue]; + _item.Value = Env->GetLvarName(_item1.IntValue, "String"); + _item.Type = "WideString"; + Env->Stack[_item1.IntValue] = _item; + _item1 = _item; + } + //edx-Src + GetRegItem(18, &_item2); + if (_item2.Flags & IF_STACK_PTR) + { + _item2 = Env->Stack[_item2.IntValue]; + if (SameText(name, "@WStrFromUStr")) + Env->Stack[_item2.IntValue].Type = "UnicodeString"; + else + Env->Stack[_item2.IntValue].Type = "String"; + } + _line = _item1.Value + " := " + _item2.Value; + Env->AddToBody(_line); + return false; + } + if (name.Pos("@_lldiv") == 1 || + SameText(name, "@__lludiv")) + { + //Argument (Int64) in edx:eax + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + if (_item1.Flags & IF_INTVAL) + { + _int64Val = (_item2.IntValue << 32) | _item1.IntValue; + _value1 = IntToStr(_int64Val); + } + else if (_item1.Flags & IF_STACK_PTR) + { + _item1 = Env->Stack[_item1.IntValue]; + _value1 = _item1.Value; + } + else + _value1 = _item1.Value; + + //Argument (Int64) in stack + _item3 = Env->Stack[_ESP_]; _ESP_ += 4; + _item4 = Env->Stack[_ESP_]; _ESP_ += 4; + if (_item3.Flags & IF_INTVAL) + { + _int64Val = (_item4.IntValue << 32) | _item3.IntValue; + _value2 = IntToStr(_int64Val); + } + else if (_item3.Flags & IF_STACK_PTR) + { + _item3 = Env->Stack[_item3.IntValue]; + _value2 = _item3.Value; + } + else + _value2 = _item3.Value; + + InitItem(&_item); + _item.Value = _value1 + " Div " + _value2; + _item.Type = "Int64"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (name.Pos("@_llmod") == 1 || + SameText(name, "@__llumod")) + { + //Argument (Int64) in edx:eax + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + if (_item1.Flags & IF_INTVAL) + { + _int64Val = (_item2.IntValue << 32) | _item1.IntValue; + _value1 = IntToStr(_int64Val); + } + else if (_item1.Flags & IF_STACK_PTR) + { + _item1 = Env->Stack[_item1.IntValue]; + _value1 = _item1.Value; + } + else + _value1 = _item1.Value; + + //Argument (Int64) in stack + _item3 = Env->Stack[_ESP_]; _ESP_ += 4; + _item4 = Env->Stack[_ESP_]; _ESP_ += 4; + if (_item3.Flags & IF_INTVAL) + { + _int64Val = (_item4.IntValue << 32) | _item3.IntValue; + _value2 = IntToStr(_int64Val); + } + else if (_item3.Flags & IF_STACK_PTR) + { + _item3 = Env->Stack[_item3.IntValue]; + _value2 = _item3.Value; + } + else + _value2 = _item3.Value; + + InitItem(&_item); + _item.Value = _value1 + " Mod " + _value2; + _item.Type = "Int64"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + if (name.Pos("@_llmul") == 1) + { + //Argument (Int64) in edx:eax + GetRegItem(16, &_item1); + GetRegItem(18, &_item2); + if (_item1.Flags & IF_INTVAL) + { + _int64Val = (_item2.IntValue << 32) | _item1.IntValue; + _value1 = IntToStr(_int64Val); + } + else if (_item1.Flags & IF_STACK_PTR) + { + _item1 = Env->Stack[_item1.IntValue]; + _value1 = _item1.Value; + } + else + _value1 = _item1.Value; + + //Argument (Int64) in stack + _item3 = Env->Stack[_ESP_]; _ESP_ += 4; + _item4 = Env->Stack[_ESP_]; _ESP_ += 4; + if (_item3.Flags & IF_INTVAL) + { + _int64Val = (_item4.IntValue << 32) | _item3.IntValue; + _value2 = IntToStr(_int64Val); + } + else if (_item3.Flags & IF_STACK_PTR) + { + _item3 = Env->Stack[_item3.IntValue]; + _value2 = _item3.Value; + } + else + _value2 = _item3.Value; + + InitItem(&_item); + _item.Value = _value1 + " * " + _value2; + _item.Type = "Int64"; + SetRegItem(16, &_item); + SetRegItem(18, &_item); + _line = "EDX_EAX := " + _item.Value + ";"; + Env->AddToBody(_line); + return false; + } + //No action + if (SameText(name, "@DoneExcept") || + SameText(name, "@LStrAddRef") || + SameText(name, "@WStrAddRef") || + SameText(name, "@UStrAddRef") || + SameText(name, "@LStrArrayClr") || + SameText(name, "@WStrArrayClr") || + SameText(name, "@UStrArrayClr") || + SameText(name, "@VarClr") || + SameText(name, "@DynArrayAddRef") || + SameText(name, "@EnsureAnsiString") || + SameText(name, "@EnsureUnicodeString") || + SameText(name, "@_IOTest") || + SameText(name, "@CheckAutoResult") || + SameText(name, "@InitExe") || + SameText(name, "@InitLib") || + SameText(name, "@IntfAddRef") || + SameText(name, "@TryFinallyExit")) + { + return false; + } + Env->ErrAdr = procAdr; + throw Exception("Under construction"); + return false; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateFormatCall() +{ + int n, _num = 0, _ofs, _esp; + String _line = "Format("; + ITEM _item; + + //eax - format + GetRegItem(16, &_item); + _line += _item.Value + ", ["; + + //edx - pointer to args + GetRegItem(18, &_item); + _ofs = _item.IntValue; + + //ecx - args num + GetRegItem(17, &_item); + _num = _item.IntValue + 1; + + for (n = 0; n < _num; n++) + { + if (n) _line += ", "; + _line += Env->Stack[_ofs].Value; + _ofs += 5; + } + _line += "]);"; + //Result + _esp = _ESP_; _ESP_ += 4; + _item = Env->Stack[_esp]; + _line = _item.Value + " := " + _line; + + Env->AddToBody(_line); + Env->LastResString = ""; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::SimulateFloatInstruction(DWORD curAdr) +{ + bool _vmt, _r, _p, _pp; + int _reg1Idx, _reg2Idx, _offset, _cmpRes, _ea, _sz, _ofs; + char *_pos; + DWORD _dd; + ITEM _item, _itemBase, _itemSrc; + PInfoRec _recN; + PFIELDINFO _fInfo; + String _name, _typeName, _val, _line, _lvarName; + + _r = false; _p = false; _pp = false; + _dd = *((DWORD*)(DisInfo.Mnem + 1)); + //fild, fld + if (_dd == 'dli' || _dd == 'dl') + { + //op Mem + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _lvarName = Env->GetLvarName(_itemSrc.IntValue, "Double"); + _item = Env->Stack[_itemSrc.IntValue]; + if (_item.Value == "") + _item.Value = _lvarName; + else + _item.Value = _lvarName + "{" + _item.Value + "}"; + //_item.Precedence = PRECEDENCE_NONE; + FPush(&_item); + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + { + InitItem(&_item); + _item.Value = _recN->GetName(); + _item.Type = _recN->type; + FPush(&_item); + return; + } + } + InitItem(&_item); + if (_itemSrc.Name != "" && !IsDefaultName(_itemSrc.Name)) + _item.Value = _itemSrc.Name; + else + _item.Value = _itemSrc.Value; + _item.Type = _itemSrc.Type; + FPush(&_item); + return; + } + } + //fst, fstp + if ((_pos = strstr(DisInfo.Mnem + 1, "st")) != 0) + { + if (_pos[2] == 'p') _p = True; + //op Mem + if (DisInfo.OpType[0] == otMEM) + { + //fst(p) [esp] + if (DisInfo.BaseReg == 20 && !DisInfo.Offset) + { + _item = Env->FStack[_TOP_]; + if (_p) FPop(); + + _lvarName = Env->GetLvarName(_ESP_, ""); + _line = _lvarName + " := " + _item.Value + ";"; + Env->AddToBody(_line); + + _ofs = _ESP_; _sz = DisInfo.OpSize; + Env->Stack[_ofs] = _item; _ofs += 4; _sz -= 4; + + InitItem(&_item); + while (_sz > 0) + { + Env->Stack[_ofs] = _item; _ofs += 4; _sz -= 4; + } + return; + } + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->FStack[_TOP_]; + if (_p) FPop(); + + _lvarName = Env->GetLvarName(_itemSrc.IntValue, "Double"); + _line = _lvarName + " := " + _item.Value + ";"; + Env->AddToBody(_line); + + _item.Precedence = PRECEDENCE_NONE; + _item.Value = _lvarName; + _ofs = _itemSrc.IntValue; _sz = DisInfo.OpSize; + Env->Stack[_ofs] = _item; _ofs += 4; _sz -= 4; + + InitItem(&_item); + while (_sz > 0) + { + Env->Stack[_ofs] = _item; _ofs += 4; _sz -= 4; + } + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + { + _item = Env->FStack[_TOP_]; + if (_p) FPop(); + _line = _recN->GetName() + " := " + _item.Value + ";"; + Env->AddToBody(_line); + return; + } + } + _item = Env->FStack[_TOP_]; + if (_p) FPop(); + + if (_itemSrc.Name != "" && !IsDefaultName(_itemSrc.Name)) + _line = _itemSrc.Name; + else + _line = _itemSrc.Value; + + _line += " := " + _item.Value + ";"; + Env->AddToBody(_line); + return; + } + //fstp - do nothing + if (DisInfo.OpType[0] == otFST) + { + return; + } + } + //fcom, fcomp, fcompp + if ((_pos = strstr(DisInfo.Mnem + 1, "com")) != 0) + { + if (_pos[3] == 'p') _p = True; + if (_pos[4] == 'p') _pp = True; + if (DisInfo.OpNum == 0) + { + CmpInfo.L = FGet(0)->Value; + CmpInfo.O = CmpOp; + CmpInfo.R = FGet(1)->Value; + if (_p) + { + FPop(); + //fcompp + if (_pp) FPop(); + } + return; + } + if (DisInfo.OpNum == 1) + { + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemSrc.IntValue]; + CmpInfo.L = FGet(0)->Value; + CmpInfo.O = CmpOp; + CmpInfo.R = Env->GetLvarName(_itemSrc.IntValue, "Double"); + if (_item.Value != "") + CmpInfo.R += "{" + _item.Value + "}"; + if (_p) + { + FPop(); + //fcompp + if (_pp) FPop(); + } + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + { + CmpInfo.L = FGet(0)->Value; + CmpInfo.O = CmpOp; + CmpInfo.R = _recN->GetName(); + if (_p) + { + FPop(); + //fcompp + if (_pp) FPop(); + } + return; + } + } + CmpInfo.L = FGet(0)->Value; + CmpInfo.O = CmpOp; + CmpInfo.R = _itemSrc.Value; + if (_p) + { + FPop(); + //fcompp + if (_pp) FPop(); + } + return; + } + } + } + //fadd, fiadd, faddp + if ((_pos = strstr(DisInfo.Mnem + 1, "add")) != 0) + { + if (_pos[3] == 'p') _p = True; + //faddp (ST(1) = ST(0) + ST(1) and pop) + if (DisInfo.OpNum == 0) + { + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + GetString(FGet(1), PRECEDENCE_ADD + 1); + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(1, &_item); + FPop(); + return; + } + //fadd r/m (ST(0) = ST(0) + r/m) + if (DisInfo.OpNum == 1) + { + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemSrc.IntValue]; + _name = _item.Name; + if (_item.Value != "") + _val = GetString(&_item, PRECEDENCE_ADD + 1); + else + _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); + + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + _name + "{" + _val + "}"; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_itemSrc.IntValue); + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + _name; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + _itemSrc.Value; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + } + //fadd ST(X), ST(Y) (ST(X) = ST(X)+ST(Y)) + if (DisInfo.OpNum == 2) + { + _reg1Idx = DisInfo.OpRegIdx[0] - 30; + _reg2Idx = DisInfo.OpRegIdx[1] - 30; + InitItem(&_item); + _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_ADD) + " + " + GetString(FGet(_reg2Idx), PRECEDENCE_ADD + 1); + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(_reg1Idx, &_item); + //faddp + if (_p) FPop(); + return; + } + } + //fsub, fisub, fsubp, fsubr, fisubr, fsubrp + if ((_pos = strstr(DisInfo.Mnem + 1, "sub")) != 0) + { + if (_pos[3] == 'r') + { + _r = true; + if (_pos[4] == 'p') _p = True; + } + if (_pos[3] == 'p') _p = True; + + //fsubp, fsubrp (ST(1) = ST(1) - ST(0) and pop) + if (DisInfo.OpNum == 0) + { + InitItem(&_item); + if (_r) + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + GetString(FGet(1), PRECEDENCE_ADD + 1); + else + _item.Value = GetString(FGet(1), PRECEDENCE_ADD) + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(1, &_item); + FPop(); + return; + } + //fsub r/m (ST(0) = ST(0) - r/m) + if (DisInfo.OpNum == 1) + { + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemSrc.IntValue]; + _name = _item.Name; + if (_item.Value != "") + _val = GetString(&_item, PRECEDENCE_ADD); + else + _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); + + InitItem(&_item); + if (_r) + _item.Value = _name + "{" + _val + "}" + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); + else + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + _name + "{" + _val + "}"; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_itemSrc.IntValue); + InitItem(&_item); + if (_r) + _item.Value = _name + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); + else + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + _name; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + InitItem(&_item); + if (_r) + _item.Value = _itemSrc.Value + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); + else + _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + _itemSrc.Value; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + } + //fsub ST(X), ST(Y) (ST(X) = ST(X)-ST(Y)) + if (DisInfo.OpNum == 2) + { + _reg1Idx = DisInfo.OpRegIdx[0] - 30; + _reg2Idx = DisInfo.OpRegIdx[1] - 30; + InitItem(&_item); + if (_r) + _item.Value = GetString(FGet(_reg2Idx), PRECEDENCE_ADD) + " - " + GetString(FGet(_reg1Idx), PRECEDENCE_ADD + 1); + else + _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_ADD) + " - " + GetString(FGet(_reg2Idx), PRECEDENCE_ADD + 1); + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(_reg1Idx, &_item); + //fsubp + if (_p) FPop(); + return; + } + } + //fmul, fimul, fmulp + if ((_pos = strstr(DisInfo.Mnem + 1, "mul")) != 0) + { + if (_pos[3] == 'p') _p = True; + //fmulp (ST(1) = ST(0) * ST(1) and pop) + if (DisInfo.OpNum == 0) + { + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + GetString(FGet(1), PRECEDENCE_MULT + 1); + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(1, &_item); + FPop(); + return; + } + //fmul r/m (ST(0) = r/m * ST(0)) + if (DisInfo.OpNum == 1) + { + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemSrc.IntValue]; + _name = _item.Name; + if (_item.Value != "") + _val = GetString(&_item, PRECEDENCE_MULT); + else + _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); + + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_MULT + 1) + " * " + _name + "{" + _val + "}"; + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_itemSrc.IntValue); + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + _name; + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + InitItem(&_item); + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + _itemSrc.Value; + _item.Precedence = PRECEDENCE_ADD; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + } + //fmul ST(X), ST(Y) (ST(X) = ST(X)*ST(Y)) + if (DisInfo.OpNum == 2) + { + _reg1Idx = DisInfo.OpRegIdx[0] - 30; + _reg2Idx = DisInfo.OpRegIdx[1] - 30; + InitItem(&_item); + _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_MULT) + " * " + GetString(FGet(_reg2Idx), PRECEDENCE_MULT + 1); + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(_reg1Idx, &_item); + //fmulp + if (_p) FPop(); + return; + } + } + //fdiv, fdivr, fidiv, fidivr, fdivp, fdivrp + if ((_pos = strstr(DisInfo.Mnem + 1, "div")) != 0) + { + if (_pos[3] == 'r') + { + _r = true; + if (_pos[4] == 'p') _p = True; + } + if (_pos[3] == 'p') _p = True; + + //fdivp (ST(1) = ST(1) / ST(0) and pop) + //fdivrp (ST(1) = ST(0) / ST(1) and pop) + if (DisInfo.OpNum == 0) + { + InitItem(&_item); + if (_r) + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + GetString(FGet(1), PRECEDENCE_MULT + 1); + else + _item.Value = GetString(FGet(1), PRECEDENCE_MULT) + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(1, &_item); + FPop(); + return; + } + //fdiv r/m (ST(0) = ST(0) / r/m) + //fdivr r/m (ST(0) = r/m / ST(0)) + if (DisInfo.OpNum == 1) + { + if (DisInfo.OpType[0] == otMEM) + { + GetMemItem(curAdr, &_itemSrc, 0); + if (_itemSrc.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemSrc.IntValue]; + _name = _item.Name; + if (_item.Value != "") + _val = GetString(&_item, PRECEDENCE_MULT); + else + _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); + + InitItem(&_item); + if (_r) + _item.Value = _name + "{" + _val + "}" + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); + else + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + _name + "{" + _val + "}"; + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + if (_itemSrc.Flags & IF_INTVAL) + { + _recN = GetInfoRec(_itemSrc.IntValue); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_itemSrc.IntValue); + InitItem(&_item); + if (_r) + _item.Value = _name + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); + else + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + _name; + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + InitItem(&_item); + if (_r) + _item.Value = _itemSrc.Value + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); + else + _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + _itemSrc.Value; + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + } + //fdiv(p) ST(X), ST(Y) (ST(X) = ST(X)/ST(Y)) + //fdivr(p) ST(X), ST(Y) (ST(X) = ST(X)/ST(Y)) + if (DisInfo.OpNum == 2) + { + _reg1Idx = DisInfo.OpRegIdx[0] - 30; + _reg2Idx = DisInfo.OpRegIdx[1] - 30; + InitItem(&_item); + if (_r) + _item.Value = GetString(FGet(_reg2Idx), PRECEDENCE_MULT) + " / " + GetString(FGet(_reg1Idx), PRECEDENCE_MULT + 1); + else + _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_MULT) + " / " + GetString(FGet(_reg2Idx), PRECEDENCE_MULT + 1); + _item.Precedence = PRECEDENCE_MULT; + _item.Type = "Extended"; + FSet(_reg1Idx, &_item); + //fdivp + if (_p) FPop(); + return; + } + } + //fabs + if (_dd == 'sba') + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "Abs(" + FGet(0)->Value + ")"; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + //fchs + if (_dd == 'shc') + { + _item = Env->FStack[_TOP_]; + _item.Value = "-" + GetString(&_item, PRECEDENCE_ATOM); + _item.Precedence = PRECEDENCE_UNARY; + //_item.Value = "-" + _item.Value; + FSet(0, &_item); + return; + } + //fld1 + if (_dd == '1dl') + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "1.0"; + _item.Type = "Extended"; + FPush(&_item); + return; + } + //fldln2 + if (_dd == 'nldl') + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "Ln(2)"; + _item.Type = "Extended"; + FPush(&_item); + return; + } + //fpatan + if (_dd == 'atap') + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + if (SameText(FGet(0)->Value, "1.0")) + _item.Value = "ArcTan(" + FGet(1)->Value + ")"; + else + _item.Value = "ArcTan(" + FGet(1)->Value + " / " + FGet(0)->Value + ")"; + _item.Type = "Extended"; + FSet(1, &_item); + FPop(); + return; + } + //fsqrt + if (_dd == 'trqs') + { + InitItem(&_item); + _item.Precedence = PRECEDENCE_ATOM; + _item.Value = "Sqrt(" + FGet(0)->Value + ")"; + _item.Type = "Extended"; + FSet(0, &_item); + return; + } + //fxch + if (_dd == 'hcx') + { + _reg1Idx = 1; + //fxch st(i) + if (DisInfo.OpNum == 1) + { + _reg1Idx = DisInfo.OpRegIdx[0] - 30; + //fxch st(0) == fxcg + if (!_reg1Idx) _reg1Idx = 1; + } + FXch(0, _reg1Idx); + return; + } + //fyl2x + if (_dd == 'x2ly') + { + InitItem(&_item); + _item.Value = GetString(FGet(1), PRECEDENCE_MULT) + " * Log2(" + GetString(FGet(0), PRECEDENCE_NONE) + ")"; + _item.Type = "Extended"; + _item.Precedence = PRECEDENCE_MULT; + FSet(1, &_item); + FPop(); + return; + } + Env->ErrAdr = curAdr; + throw Exception("Under construction"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::AddToBody(String src) +{ + Body->Add(src); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompileEnv::AddToBody(TStringList* src) +{ + for (int n = 0; n < src->Count; n++) + { + Body->Add(src->Strings[n]); + } +} +//--------------------------------------------------------------------------- +bool __fastcall TDecompileEnv::IsExitAtBodyEnd() +{ + return SameText(Body->Strings[Body->Count - 1], "Exit;"); +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::GetCycleIdx(PIDXINFO IdxInfo, DISINFO* ADisInfo) +{ + ITEM _item; + + IdxInfo->IdxType = itUNK; + IdxInfo->IdxValue = 0; + IdxInfo->IdxStr = ADisInfo->Op1; + + if (ADisInfo->OpType[0] == otREG) + { + IdxInfo->IdxType = itREG; + IdxInfo->IdxValue = ADisInfo->OpRegIdx[0]; + return; + } + if (ADisInfo->OpType[0] == otMEM) + { + //Offset + if (ADisInfo->BaseReg == -1) + { + IdxInfo->IdxType = itGVAR; + IdxInfo->IdxValue = ADisInfo->Offset; + IdxInfo->IdxStr = ADisInfo->Op1; + return; + } + //[ebp-N] + if (ADisInfo->BaseReg == 21) + { + GetRegItem(ADisInfo->BaseReg, &_item); + IdxInfo->IdxType = itLVAR; + IdxInfo->IdxValue = _item.IntValue + ADisInfo->Offset;//LocBase - ((int)_item.Value + ADisInfo->Offset); + return; + } + //[esp-N] + if (ADisInfo->BaseReg == 20) + { + IdxInfo->IdxType = itLVAR; + IdxInfo->IdxValue = _ESP_ + ADisInfo->Offset;//LocBase - (_ESP_ + ADisInfo->Offset); + return; + } + } +} +//--------------------------------------------------------------------------- +String __fastcall TDecompiler::GetCycleFrom() +{ + ITEM _item; + + if (DisInfo.OpType[1] == otIMM) return String(DisInfo.Immediate); + if (DisInfo.OpType[1] == otREG) + { + GetRegItem(DisInfo.OpRegIdx[1], &_item); + return _item.Value; + } + if (DisInfo.OpType[1] == otMEM) + { + //Offset + if (DisInfo.BaseReg == -1) return GetGvarName(DisInfo.Offset); + //[ebp-N] + if (DisInfo.BaseReg == 21) + { + GetRegItem(DisInfo.BaseReg, &_item); + _item = Env->Stack[_item.IntValue + DisInfo.Offset]; + return _item.Value; + } + //[esp-N] + if (DisInfo.BaseReg == 20) + { + GetRegItem(DisInfo.BaseReg, &_item); + _item = Env->Stack[_ESP_ + DisInfo.Offset]; + return _item.Value; + } + } + return "?"; +} +//--------------------------------------------------------------------------- +String __fastcall TDecompiler::GetCycleTo() +{ + ITEM _item; + + if (DisInfo.OpType[0] == otREG) + { + GetRegItem(DisInfo.OpRegIdx[0], &_item); + return _item.Value; + } + if (DisInfo.OpType[0] == otMEM) + { + //Offset + if (DisInfo.BaseReg == -1) return GetGvarName(DisInfo.Offset); + //[ebp-N] + if (DisInfo.BaseReg == 21) + { + GetRegItem(DisInfo.BaseReg, &_item); + _item = Env->Stack[_item.IntValue + DisInfo.Offset]; + return _item.Value; + } + //[esp-N] + if (DisInfo.BaseReg == 20) + { + GetRegItem(DisInfo.BaseReg, &_item); + _item = Env->Stack[_ESP_ + DisInfo.Offset]; + return _item.Value; + } + } + return "?"; +} +//--------------------------------------------------------------------------- +DWORD __fastcall TDecompiler::DecompileGeneralCase(DWORD fromAdr, DWORD markAdr, PLoopInfo loopInfo, int N) +{ + //bool _changed = false; + int _N, _N1 = N, _N2; + DWORD _dd; + DWORD _curAdr = fromAdr, _adr, _endAdr = 0, _begAdr; + int _curPos = Adr2Pos(fromAdr); + int _len, _instrLen; + TDecompiler *de; + DISINFO _disInfo; + + while (1) + { + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + //Switch at current address + if (IsFlagSet(cfSwitch, _curPos)) + { + de = new TDecompiler(Env); + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + de->ClearStop(_curAdr); + try + { + _adr = de->DecompileCaseEnum(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + return _endAdr; + } + //Switch at next address + if (IsFlagSet(cfSwitch, _curPos + _len)) + { + _N = _disInfo.Immediate; + //add or sub + if (_dd == 'dda') _N = -_N; + _curAdr += _len; _curPos += _len; + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(_curAdr);//markAdr + de->ClearStop(_curAdr); + try + { + _adr = de->DecompileCaseEnum(_begAdr, _N, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + return _endAdr; + } + //cmp reg, imm + if (_dd == 'pmc' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) + { + _N = _disInfo.Immediate; + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bj' || _dd == 'gj' || _dd == 'egj') + { + _adr = DecompileGeneralCase(_disInfo.Immediate, markAdr, loopInfo, _N1); + if (_adr > _endAdr) _endAdr = _adr; + + _curAdr += _len; _curPos += _len; + + _len = Disasm.Disassemble(Code + _curPos, (__int64)(_curAdr), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + Env->AddToBody(String(_N) + ":"); + _begAdr = _disInfo.Immediate; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + de->ClearStop(_begAdr); + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + + _curAdr += _len; _curPos += _len; + } + continue; + } + } + //dec reg; sub reg, imm + if ((_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'ced' && _disInfo.OpType[0] == otREG)) + { + if (_dd == 'bus') + _N2 = _disInfo.Immediate; + else + _N2 = 1; + _N1 += _N2; + if (_disInfo.OpRegIdx[0] < 8) + _N1 &= 0xFF; + else if (_disInfo.OpRegIdx[0] < 16) + _N1 &= 0xFFFF; + + _curAdr += _len; _curPos += _len; + + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bj') + { + Env->AddToBody(String(_N1 - _N2) + ".." + String(_N1 - 1) + ":"); + _begAdr = _disInfo.Immediate; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + de->ClearStop(_begAdr); + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + + _curAdr += _len; _curPos += _len; + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + Env->AddToBody(String(_N1) + ":"); + _begAdr = _disInfo.Immediate; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + de->ClearStop(_begAdr); + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + + _curAdr += _len; _curPos += _len; + } + continue; + } + if (_dd == 'zj' || _dd == 'ej') + { + Env->AddToBody(String(_N1) + ":"); + _begAdr = _disInfo.Immediate; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + de->ClearStop(_begAdr); + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + + _curAdr += _len; _curPos += _len; + continue; + } + if (_dd == 'znj' || _dd == 'enj') + { + Env->AddToBody(String(_N1) + ":"); + _begAdr = _curAdr + _len; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + break; + } + } + //inc reg; add reg, imm + if ((_dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'cni' && _disInfo.OpType[0] == otREG)) + { + if (_dd == 'dda') + _N2 = _disInfo.Immediate; + else + _N2 = 1; + _N1 -= _N2; + if (_disInfo.OpRegIdx[0] < 8) + _N1 &= 0xFF; + else if (_disInfo.OpRegIdx[0] < 16) + _N1 &= 0xFFFF; + + _curAdr += _len; _curPos += _len; + + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + Env->AddToBody(String(_N1) + ":"); + _begAdr = _disInfo.Immediate; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->MarkGeneralCase(markAdr); + de->ClearStop(_begAdr); + try + { + Env->AddToBody("begin"); + _adr = de->Decompile(_begAdr, 0, loopInfo); + if (_adr > _endAdr) _endAdr = _adr; + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("GeneralCase->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + + _curAdr += _len; _curPos += _len; + continue; + } + } + if (_dd == 'pmj') break; + } + return _endAdr; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::MarkGeneralCase(DWORD fromAdr) +{ + DWORD _dd; + DWORD _curAdr = fromAdr; + int _curPos = Adr2Pos(fromAdr); + int _len, _instrLen; + DISINFO _disInfo; + + while (1) + { + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + //Switch at current address + if (IsFlagSet(cfSwitch, _curPos)) + { + //Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0);//ja + MarkCaseEnum(_curAdr); + return; + } + //Switch at next address + if (IsFlagSet(cfSwitch, _curPos + _len)) + { + _curPos += _len; _curAdr += _len; + //_len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0);//ja + //_curPos += _len; _curAdr += _len; + MarkCaseEnum(_curAdr); + return; + } + //cmp reg, imm + if (_dd == 'pmc' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bj' || _dd == 'gj' || _dd == 'egj') + { + MarkGeneralCase(_disInfo.Immediate); + + _curAdr += _len; _curPos += _len; + + _len = Disasm.Disassemble(Code + _curPos, (__int64)(_curAdr), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + SetStop(_disInfo.Immediate); + _curAdr += _len; _curPos += _len; + } + continue; + } + } + //sub reg, imm; dec reg + if ((_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'ced' && _disInfo.OpType[0] == otREG)) + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bus') + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + } + if (_dd == 'bj') + { + SetStop(_disInfo.Immediate); + _curAdr += _len; _curPos += _len; + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + SetStop(_disInfo.Immediate); + _curAdr += _len; _curPos += _len; + } + continue; + } + if (_dd == 'zj' || _dd == 'ej') + { + SetStop(_disInfo.Immediate); + _curAdr += _len; _curPos += _len; + continue; + } + if (_dd == 'znj' || _dd == 'enj') + break; + } + //add reg, imm; inc reg + if ((_dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'cni' && _disInfo.OpType[0] == otREG)) + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bus') + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bj') + { + SetStop(_disInfo.Immediate); + _curAdr += _len; _curPos += _len; + continue; + } + } + if (_dd == 'zj' || _dd == 'ej') + { + SetStop(_disInfo.Immediate); + _curAdr += _len; _curPos += _len; + continue; + } + } + if (_dd == 'pmj') + { + SetStop(_disInfo.Immediate); + break; + } + } +} +//--------------------------------------------------------------------------- +int __fastcall TDecompiler::GetArrayFieldOffset(String ATypeName, int AFromOfs, int AScale, String& name, String& type) +{ + bool _vmt; + int _size, _lIdx, _hIdx, _ofs, _fofs; + int _classSize = GetClassSize(GetClassAdr(ATypeName)); + int _offset = AFromOfs; + + while (1) + { + if (_offset >= _classSize) break; + _fofs = GetField(ATypeName, _offset, name, type); + if (_fofs >= 0) + return _offset; + /* + if (_fofs >= 0 && GetTypeKind(type, &_size) == ikArray && GetArrayIndexes(type, 1, &_lIdx, &_hIdx)) + { + _size = GetArrayElementTypeSize(type); + _ofs = AFromOfs + AScale * _lIdx; + if (_ofs >= _fofs && _ofs <= _fofs + (_hIdx - _lIdx) * _size) + return _fofs; + } + //Try next offset + _offset++; + */ + } + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::GetInt64ItemFromStack(int Esp, PITEM Dst) +{ + BYTE _binData[8]; + __int64 _int64Val; + ITEM _item; + + InitItem(Dst); + memset((void*)_binData, 0, 8); + _item = Env->Stack[Esp]; + memmove((void*)_binData, (void*)&_item.IntValue, 4); + _item = Env->Stack[Esp + 4]; + memmove((void*)(_binData + 4), (void*)&_item.IntValue, 4); + memmove((void*)&_int64Val, _binData, 8); + Dst->Value = IntToStr(_int64Val); + Dst->Type = "Int64"; +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::GetFloatItemFromStack(int Esp, PITEM Dst, int FloatType) +{ + BYTE _binData[16]; + float _singleVal; + double _doubleVal; + long double _extendedVal; + double _realVal; + Comp _compVal; + Currency _currVal; + ITEM _item; + + InitItem(Dst); + _item = Env->Stack[Esp]; + if (!(_item.Flags & IF_INTVAL)) + { + Dst->Value = _item.Value; + Dst->Type = _item.Type; + return; + } + memset((void*)_binData, 0, 16); + memmove((void*)_binData, (void*)&_item.IntValue, 4); + if (FloatType == FT_SINGLE) + { + memmove((void*)&_singleVal, _binData, 4); + Dst->Value = FloatToStr(_singleVal); + Dst->Type = "Single"; + return; + } + if (FloatType == FT_REAL) + { + memmove((void*)&_realVal, _binData, 4); + Dst->Value = FloatToStr(_realVal); + Dst->Type = "Real"; + return; + } + _item = Env->Stack[Esp + 4]; + memmove((void*)(_binData + 4), (void*)&_item.IntValue, 4); + if (FloatType == FT_DOUBLE) + { + memmove((void*)&_doubleVal, _binData, 8); + Dst->Value = FloatToStr(_doubleVal); + Dst->Type = "Double"; + return; + } + if (FloatType == FT_COMP) + { + memmove((void*)&_compVal, _binData, 8); + Dst->Value = FloatToStr(_compVal); + Dst->Type = "Comp"; + return; + } + if (FloatType == FT_CURRENCY) + { + memmove((void*)&_currVal.Val, _binData, 8); + Dst->Value = _currVal.operator AnsiString(); + Dst->Type = "Currency"; + return; + } + _item = Env->Stack[Esp + 8]; + memmove((void*)(_binData + 8), (void*)&_item.IntValue, 4); + if (FloatType == FT_EXTENDED) + { + memmove((void*)&_extendedVal, _binData, 10); + try + { + Dst->Value = FloatToStr(_extendedVal); + Dst->Type = "Extended"; + } + catch(Exception &exception) + { + throw Exception("Extended type error" + exception.Message); + } + return; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDecompiler::GetMemItem(int CurAdr, PITEM Dst, BYTE Op) +{ + bool _vmt; + BYTE _kind; + int _offset, _foffset, _pos, _size, _idx, _idx1, _mod, _fofs; + DWORD _adr; + PInfoRec _recN, _recN1; + ITEM _item, _itemBase, _itemIndx; + String _fname, _name, _type, _typeName, _iname, _value, _text, _lvarName; + + InitItem(Dst); + _offset = DisInfo.Offset; + if (DisInfo.BaseReg == -1) + { + if (DisInfo.IndxReg == -1) + { + //[Offset] + if (IsValidImageAdr(_offset)) + { + Dst->Flags = IF_INTVAL; + Dst->IntValue = _offset; + return; + } + Env->ErrAdr = CurAdr; + throw Exception("Address is outside program image"); + } + //[Offset + IndxReg*Scale] + if (IsValidImageAdr(_offset)) + { + _recN = GetInfoRec(_offset); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_offset); + Dst->Value = _name + "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; + return; + } + Env->ErrAdr = CurAdr; + throw Exception("Address is outside program image"); + } + GetRegItem(DisInfo.BaseReg, &_itemBase); + //[BaseReg + Offset] + if (DisInfo.IndxReg == -1) + { + //[esp+N] + if (DisInfo.BaseReg == 20) + { + Dst->Flags = IF_STACK_PTR; + Dst->IntValue = _ESP_ + _offset; + _item = Env->Stack[_ESP_ + _offset]; + //Field + if (_item.Flags & IF_FIELD) + { + _foffset = _item.Offset; + _offset -= _foffset; + _fname = GetRecordFields(_foffset, Env->Stack[_ESP_ + _offset].Type); + _typeName = ExtractType(_fname); + _name = Env->GetLvarName(_ESP_ + _offset, _typeName); + if (_fname.Pos(":")) + { + Dst->Value = _name + "." + ExtractName(_fname); + Dst->Type = _typeName; + } + else + { + Dst->Value = _name + ".f" + Val2Str0(_foffset); + } + Dst->Name = Dst->Value; + return; + } + _value = Env->GetLvarName(_ESP_ + _offset, ""); + if (_item.Value != "") _value += "{" + _item.Value + "}"; + Dst->Value = _value; + return; + } + //lea reg, [ebp + N], bpBased + if (Op == OP_LEA && DisInfo.BaseReg == 21 && DisInfo.IndxReg == -1 && Env->BpBased) + { + Dst->Flags = IF_STACK_PTR; + Dst->IntValue = _itemBase.IntValue + _offset; + return; + } + //Embedded procedures + if (Env->Embedded) + { + if (_itemBase.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemBase.IntValue + _offset]; + //Set flag IF_EXTERN_VAR and exit + if (SameText(_item.Name, "extebp")) + { + Dst->Flags = IF_EXTERN_VAR; + return; + } + } + if (_itemBase.Flags & IF_EXTERN_VAR) + { + if (_offset < 0) + Dst->Value = "extlvar_" + Val2Str0(-_offset); + if (_offset > 0) + Dst->Value = "extarg_" + Val2Str0(_offset); + return; + } + } + //[reg-N] + if (_itemBase.Flags & IF_STACK_PTR) + { + //xchg ecx,[ebp-XXX] - special processing + if (Op == OP_XCHG) + { + Dst->Flags = IF_STACK_PTR; + Dst->IntValue = _itemBase.IntValue + _offset; + Dst->Value = _itemBase.Value; + Dst->Name = _itemBase.Name; + return; + } + if (_itemBase.Flags & IF_ARG) + { + Dst->Flags = IF_STACK_PTR; + Dst->IntValue = _itemBase.IntValue + _offset; + Dst->Value = _itemBase.Value; + Dst->Name = _itemBase.Name; + return; + } + if (_itemBase.Flags & IF_ARRAY_PTR) + { + Dst->Flags = IF_STACK_PTR; + Dst->IntValue = _itemBase.IntValue + _offset; + if (_itemBase.Value != "") Dst->Value = _itemBase.Value + "[]"; + if (_itemBase.Name != "") Dst->Name = _itemBase.Name + "[]"; + return; + } + _item = Env->Stack[_itemBase.IntValue + _offset]; + //Arg + if (_item.Flags & IF_ARG) + { + //Dst->Flags = IF_STACK_PTR; + //Dst->IntValue = _itemBase.IntValue + _offset; + AssignItem(Dst, &_item); + Dst->Flags &= ~IF_ARG; + //Dst->Value = _item.Name; + //Dst->Name = _item.Name; + return; + } + //Var + if (_item.Flags & IF_VAR) + { + _item.Flags &= ~IF_VAR; + _item.Type = "^" + _item.Type; + AssignItem(Dst, &_item); + Dst->Name = Env->GetLvarName(_itemBase.IntValue + _offset, ""); + return; + } + //Field + if (_item.Flags & IF_FIELD) + { + _foffset = _item.Offset; + _offset -= _foffset; + _fname = GetRecordFields(_foffset, Env->Stack[_itemBase.IntValue + _offset].Type); + _typeName = ExtractType(_fname); + _name = Env->GetLvarName(_itemBase.IntValue + _offset, _typeName); + if (_fname.Pos(":")) + { + Dst->Value = _name + "." + ExtractName(_fname); + Dst->Type = _typeName; + } + else + { + Dst->Value = _name + ".f" + Val2Str0(_foffset); + } + Dst->Name = _name; + return; + } + //Not interface + if (_item.Type == "" || GetTypeKind(_item.Type, &_size) != ikInterface) + { + _lvarName = Env->GetLvarName(_itemBase.IntValue + _offset, ""); + Env->Stack[_itemBase.IntValue + _offset].Name = _lvarName; + Dst->Flags = IF_STACK_PTR; + Dst->IntValue = _itemBase.IntValue + _offset; + Dst->Value = _lvarName; + Dst->Name = Dst->Value; + return; + } + } + //[BaseReg] + if (!_offset) + { + _typeName = _itemBase.Type; + if (_itemBase.Flags & IF_VAR) + { + AssignItem(Dst, &_itemBase); + Dst->Flags &= ~IF_VAR; + Dst->Name = ""; + return; + } + if (_itemBase.Flags & IF_RECORD_FOFS) + { + _value = _itemBase.Value; + if (_itemBase.Flags & IF_ARRAY_PTR) + _value += "[]"; + _text = GetRecordFields(_itemBase.Offset, _itemBase.Type); + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_itemBase.Offset); + _typeName = _text; + } + Dst->Value = _value; + Dst->Type = _typeName; + Dst->Name = ""; + return; + } + if (_itemBase.Flags & IF_ARRAY_PTR) + { + Dst->Value = _itemBase.Value + "[]"; + Dst->Type = GetArrayElementType(_typeName); + Dst->Name = ""; + return; + } + if (_itemBase.Flags & IF_STACK_PTR) + { + _item = Env->Stack[_itemBase.IntValue]; + AssignItem(Dst, &_item); + return; + } + if (_itemBase.Flags & IF_INTVAL) + { + _adr = _itemBase.IntValue; + if (IsValidImageAdr(_adr)) + { + _recN = GetInfoRec(_adr); + if (_recN) + { + Dst->Value = _recN->GetName(); + Dst->Type = _recN->type; + return; + } + } + } + if (_typeName == "") + { + _typeName = "Pointer"; + //_name = GetDecompilerRegisterName(DisInfo.BaseReg); + //_typeName = ManualInput(CurProcAdr, CurAdr, "Define type of base register (" + _name + ")", "Type:"); + //if (_typeName == "") + //{ + // Env->ErrAdr = CurAdr; + // throw Exception("Bye!"); + //} + } + if (_typeName[1] == '^')//Pointer to var + { + _value = _itemBase.Value; + _typeName = GetTypeDeref(_typeName); + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikRecord) + { + _text = GetRecordFields(0, _typeName); + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f0"; + _typeName = _text; + } + } + if (_kind == ikArray) + { + _value += "[ofs=" + String(_offset) + "]"; + } + Dst->Value = _value; + Dst->Name = GetDecompilerRegisterName(DisInfo.BaseReg); + Dst->Type = _typeName; + return; + } + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikEnumeration) + { + Dst->Value = GetEnumerationString(_typeName, _itemBase.Value); + Dst->Type = _typeName; + return; + } + if (_kind == ikLString || _kind == ikString) + { + Dst->Value = _itemBase.Value + "[1]"; + Dst->Type = "Char"; + return; + } + if (_kind == ikRecord) + { + _text = GetRecordFields(_offset, _typeName); + if (_text.Pos(":")) + { + _value = _itemBase.Value + "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value = _itemBase.Value + ".f" + Val2Str0(_offset); + _typeName = _text; + } + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + + Dst->Flags = IF_VMT_ADR; + if (_itemBase.Flags & IF_INTERFACE) + { + Dst->Flags |= IF_INTERFACE; + Dst->Value = _itemBase.Value; + } + Dst->IntValue = GetClassAdr(_typeName); + Dst->Type = _typeName; + return; + } + //[BaseReg+Offset] + if (IsValidImageAdr(_offset)) + { + _recN = GetInfoRec(_offset); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_offset); + Dst->Value = _name + "[" + GetDecompilerRegisterName(DisInfo.BaseReg) + "]"; + return; + } + if (_itemBase.Flags & IF_RECORD_FOFS) + { + _value = _itemBase.Value; + if (_itemBase.Flags & IF_ARRAY_PTR) + _value += "[]"; + _text = GetRecordFields(_itemBase.Offset + _offset, _itemBase.Type); + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_itemBase.Offset + _offset); + _typeName = _text; + } + Dst->Value = _value; + Dst->Type = _typeName; + Dst->Name = ""; + return; + } + if (_itemBase.Flags & IF_ARRAY_PTR) + { + if ((_itemBase.Flags & IF_STACK_PTR) && Env->Stack[_itemBase.IntValue].Value != "") + Dst->Value = Env->Stack[_itemBase.IntValue].Value + "["; + else + Dst->Value = GetDecompilerRegisterName(DisInfo.BaseReg) + "["; + if (_offset > 0) + Dst->Value += " + " + String(_offset); + else if (_offset < 0) + Dst->Value += " - " + String(-_offset); + Dst->Value += "]"; + return; + } + _typeName = _itemBase.Type; + if (_typeName == "") + { + _typeName = "Pointer"; + //_name = GetDecompilerRegisterName(DisInfo.BaseReg); + //_typeName = ManualInput(CurProcAdr, CurAdr, "Define type of base register (" + _name + ")", "Type:"); + //if (_typeName == "") + //{ + // Env->ErrAdr = CurAdr; + // throw Exception("Bye!"); + //} + } + if (_typeName[1] == '^') _typeName = GetTypeDeref(_typeName); + + _itemBase.Flags = 0; + if (_itemBase.Value == "") + _itemBase.Value = GetDecompilerRegisterName(DisInfo.BaseReg); + _itemBase.Type = _typeName; + SetRegItem(DisInfo.BaseReg, &_itemBase); + + _iname = _itemBase.Value; + _kind = GetTypeKind(_typeName, &_size); + if (_kind == ikLString || _kind == ikString) + { + _value = _iname + "[" + String(_offset + 1) + "]"; + _typeName = "Char"; + } + else if (_kind == ikRecord) + { + if (_itemBase.Value != "") + _value = _itemBase.Value; + else + _value = GetDecompilerRegisterName(DisInfo.BaseReg); + if (Op == OP_LEA)//address of field with ofs=_offset in structure _typeName + { + Dst->Flags = IF_RECORD_FOFS; + Dst->Value = _value; + Dst->Type = _typeName; + Dst->Offset = _offset; + return; + } + _text = GetRecordFields(_offset, _typeName); + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_offset); + _typeName = _text; + } + } + else if (_kind == ikArray) + { + _value = _iname + "[ofs=" + String(_offset) + "]"; + } + else if (_kind == ikDynArray) + { + _typeName = GetArrayElementType(_typeName); + if (_typeName == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Type of array elements not found"); + } + if (GetTypeKind(_typeName, &_size) == ikRecord) + { + int _k = 0; + _size = GetRecordSize(_typeName); + if (_offset < 0) + { + while (1) + { + _offset += _size; _k--; + if (_offset >= 0 && _offset < _size) break; + } + } + if (_offset >= _size) + { + while (1) + { + _offset -= _size; _k++; + if (_offset >= 0 && _offset < _size) break; + } + } + _text = GetRecordFields(_offset, _typeName); + if (_text == "") + { + _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset), "[Name]:Type:"); + if (_text == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Bye!"); + } + } + _value = _itemBase.Value + "[" + String(_k) + "]"; + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_offset); + _typeName = _text; + } + } + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + else if (_kind == ikVMT || _kind == ikClass) + { + _fofs = GetField(_typeName, _offset, _name, _type); + if (_fofs < 0) + { + _text = ManualInput(CurProcAdr, CurAdr, "Define correct type of field " + _typeName + ".f" + Val2Str0(_offset), "Type:"); + if (_text == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Bye!"); + } + _recN1 = GetInfoRec(GetClassAdr(_typeName)); + _recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, _offset, -1, "", _text); + + _fofs = GetField(_typeName, _offset, _name, _type); + if (_fofs < 0) + { + Env->ErrAdr = CurAdr; + throw Exception("Field f" + Val2Str0(_offset) + " not found"); + } + } + _value = _name; + _typeName = _type; + _foffset = _fofs; + + //if (Op != OP_LEA) + //{ + _kind = GetTypeKind(_typeName, &_size); + //Interface + if (_kind == ikInterface) + { + _typeName[1] = 'T'; + Dst->Flags = IF_INTERFACE; + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + //Record + if (_kind == ikRecord) + { + _text = GetRecordFields(_offset - _foffset, _typeName); + if (_text == "") + { + _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset - _fofs), "[Name]:Type:"); + if (_text == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Bye!"); + } + } + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_offset); + _typeName = _text; + } + } + //Array + if (_kind == ikArray) + { + _value += "[ofs=" + String(_offset - _foffset) + "]"; + } + if (!SameText(_iname, "Self")) _value = _iname + "." + _value; + //} + } + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + //[BaseReg + IndxReg*Scale + Offset] + else + { + GetRegItem(DisInfo.IndxReg, &_itemIndx); + if (Op == OP_LEA) + { + if (_itemBase.Flags & IF_STACK_PTR) Dst->Flags |= IF_STACK_PTR; + Dst->Value = GetDecompilerRegisterName(DisInfo.BaseReg) + " + " + GetDecompilerRegisterName(DisInfo.IndxReg) + " * " + String(DisInfo.Scale); + if (_offset > 0) + Dst->Value += " + " + String(_offset); + else if (_offset < 0) + Dst->Value += " - " + String(-_offset); + return; + } + _typeName = _itemBase.Type; + if (_typeName == "") + { + //esp + if (DisInfo.BaseReg == 20) + { + Dst->Value = Env->GetLvarName(_ESP_ + _offset + DisInfo.Scale, "") + "[" + _itemIndx.Value + "]"; + return; + } + //ebp + if (DisInfo.BaseReg == 21 && (_itemBase.Flags & IF_STACK_PTR)) + { + Dst->Value = Env->GetLvarName(_itemBase.IntValue + _offset + DisInfo.Scale, "") + "[" + _itemIndx.Value + "]"; + return; + } + _kind = 0; + //Lets try analyze _itemBase if it is address + if (_itemBase.Flags & IF_INTVAL) + { + _adr = _itemBase.IntValue; + if (IsValidImageAdr(_adr)) + { + _recN = GetInfoRec(_adr); + if (_recN) + { + _kind = _recN->kind; + if (_recN->type != "" && (_kind == ikUnknown || _kind == ikData)) + _kind = GetTypeKind(_recN->type, &_size); + } + } + } + while (_kind == 0 || _kind == ikData) + { + _text = "Pointer"; + //_text = ManualInput(CurProcAdr, CurAdr, "Define type of base register", "Type:"); + //if (_text == "") + //{ + // Env->ErrAdr = CurAdr; + // throw Exception("Bye!"); + //} + _typeName = _text; + _kind = GetTypeKind(_typeName, &_size); + } + } + else + { + if (_typeName[1] == '^') _typeName = GetTypeDeref(_typeName); + + _kind = GetTypeKind(_typeName, &_size); + while (_kind != ikClass && _kind != ikVMT && _kind != ikLString && + _kind != ikCString && _kind != ikPointer && _kind != ikRecord && + _kind != ikArray && _kind != ikDynArray) + { + _text = "Pointer"; + //_text = ManualInput(CurProcAdr, CurAdr, "Define type of base register", "Type:"); + //if (_text == "") + //{ + // Env->ErrAdr = CurAdr; + // throw Exception("Bye!"); + //} + _typeName = _text; + _kind = GetTypeKind(_typeName, &_size); + } + } + if (_kind == ikClass || _kind == ikVMT) + { + _fofs = GetArrayFieldOffset(_typeName, _offset, DisInfo.Scale, _name, _type); + while (_fofs < 0) + { + _text = ManualInput(CurProcAdr, CurAdr, "Define actual offset (in hex) of array field", "Offset:"); + if (_text == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Bye!"); + } + sscanf(_text.c_str(), "%lX", &_offset); + _fofs = GetArrayFieldOffset(_typeName, _offset, DisInfo.Scale, _name, _type); + } + if (!SameText(_itemBase.Value, "Self")) _value = _itemBase.Value + "."; + if (_name != "") + _value += _name; + else + _value += "f" + Val2Str0(_fofs); + _value += "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; + + Dst->Value = _value; + Dst->Type = GetArrayElementType(_type); + return; + } + if (_kind == ikLString || _kind == ikCString || _kind == ikPointer) + { + Dst->Value = GetDecompilerRegisterName(DisInfo.BaseReg) + "[" + GetDecompilerRegisterName(DisInfo.IndxReg); + if (_kind == ikLString) _offset++; + if (_offset > 0) + Dst->Value += " + " + String(_offset); + else if (_offset < 0) + Dst->Value += " - " + String(-_offset); + Dst->Value += "]"; + Dst->Type = "Char"; + return; + } + if (_kind == ikRecord) + { + _value = _itemBase.Value; + _text = GetRecordFields(_offset + DisInfo.Scale, _typeName); + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_offset); + _typeName = _text; + } + if (GetTypeKind(_typeName, &_size) == ikArray) + { + _value += "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; + _typeName = GetArrayElementType(_typeName); + } + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + if (_kind == ikArray) + { + if (_itemBase.Flags & IF_INTVAL) + { + _adr = _itemBase.IntValue; + _recN = GetInfoRec(_adr); + if (_recN && _recN->HasName()) + _name = _recN->GetName(); + else + _name = GetGvarName(_adr); + } + _name = _itemBase.Value; + _typeName = GetArrayElementType(_typeName); + if (_typeName == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Type of array elements not found"); + } + if (GetTypeKind(_typeName, &_size) == ikRecord) + { + int _k = 0; + _size = GetRecordSize(_typeName); + if (_offset < 0) + { + while (1) + { + _offset += _size; _k--; + if (_offset >= 0 && _offset < _size) break; + } + } + if (_offset > _size) + { + while (1) + { + _offset -= _size; _k++; + if (_offset >= 0 && _offset < _size) break; + } + } + _text = GetRecordFields(_offset, _typeName); + if (_text == "") + { + _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset), "[Name]:Type:"); + if (_text == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Bye!"); + } + } + _value = _name + "["; + if (_itemIndx.Value != "") + _value += _itemIndx.Value; + else + _value += GetDecompilerRegisterName(DisInfo.IndxReg); + if (_k < 0) + _value += " - " + String(-_k) + "]"; + else if (_k > 0) + _value += " + " + String(_k) + "]"; + else + _value += "]"; + + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_offset); + _typeName = _text; + } + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + + if (!GetArrayIndexes(_itemBase.Type, 1, &_idx, &_idx1)) + { + Env->ErrAdr = CurAdr; + throw Exception("Incorrect array definition"); + } + _mod = _offset % DisInfo.Scale; + if (_mod) + { + Env->ErrAdr = CurAdr; + throw Exception("Array element is record"); + } + + if (_itemIndx.Value != "") + _value = _itemBase.Value + "[" + _itemIndx.Value + "]"; + else + _value = _itemBase.Value + "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; + Dst->Value = _value; + Dst->Type = GetArrayElementType(_itemBase.Type); + return; + } + if (_kind == ikDynArray) + { + _typeName = GetArrayElementType(_typeName); + if (_typeName == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Type of array elements not found"); + } + _value = _itemBase.Value + "["; + if (_itemIndx.Value != "") + _value += _itemIndx.Value; + else + _value += GetDecompilerRegisterName(DisInfo.IndxReg); + _value += "]"; + + if (GetTypeKind(_typeName, &_size) == ikRecord) + { + int _k = 0; + _size = GetRecordSize(_typeName); + if (_offset < 0) + { + while (1) + { + _offset += _size; _k--; + if (_offset >= 0 && _offset < _size) break; + } + } + if (_offset > _size) + { + while (1) + { + _offset -= _size; _k++; + if (_offset >= 0 && _offset < _size) break; + } + } + _text = GetRecordFields(_offset, _typeName); + if (_text == "") + { + _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset), "[Name]:Type:"); + if (_text == "") + { + Env->ErrAdr = CurAdr; + throw Exception("Bye!"); + } + } + _value = _itemBase.Value + "["; + if (_itemIndx.Value != "") + _value += _itemIndx.Value; + else + _value += GetDecompilerRegisterName(DisInfo.IndxReg); + if (_k < 0) + _value += " - " + String(-_k) + "]"; + else if (_k > 0) + _value += " + " + String(_k) + "]"; + else + _value += "]"; + + if (_text.Pos(":")) + { + _value += "." + ExtractName(_text); + _typeName = ExtractType(_text); + } + else + { + _value += ".f" + Val2Str0(_offset); + _typeName = _text; + } + } + Dst->Value = _value; + Dst->Type = _typeName; + return; + } + Env->ErrAdr = CurAdr; + throw Exception("Under construction"); + } +} +//--------------------------------------------------------------------------- +String __fastcall TDecompiler::GetStringArgument(PITEM item) +{ + int _idx, _ap, _len, _size; + DWORD _adr; + PInfoRec _recN; + String _key; + + if (item->Name != "") return item->Name; + + if (item->Flags & IF_STACK_PTR) + { + Env->Stack[item->IntValue].Type = "String"; + return Env->GetLvarName(item->IntValue, "String"); + } + else if (item->Flags & IF_INTVAL) + { + _adr = item->IntValue; + if (_adr == 0) + { + return ""; + } + else if (IsValidImageAdr(_adr)) + { + _ap = Adr2Pos(_adr); + if (_ap >= 0) + { + _recN = GetInfoRec(_adr); + if (_recN && (_recN->kind == ikLString || _recN->kind == ikWString || _recN->kind == ikUString)) + return _recN->GetName(); + + _len = wcslen((wchar_t*)(Code + _ap)); + WideString wStr = WideString((wchar_t*)(Code + _ap)); + _size = WideCharToMultiByte(CP_ACP, 0, wStr, -1, 0, 0, 0, 0); + if (_size) + { + char* tmpBuf = new char[_size + 1]; + WideCharToMultiByte(CP_ACP, 0, wStr, -1, (LPSTR)tmpBuf, _size, 0, 0); + String str = TransformString(tmpBuf, _size); + delete[] tmpBuf; + return str; + } + } + else + { + _key = Val2Str8(_adr); + _idx = BSSInfos->IndexOf(_key); + if (_idx != -1) + _recN = (PInfoRec)BSSInfos->Objects[_idx]; + if (_recN) + return _recN->GetName(); + else + return item->Value; + } + } + else + { + return item->Value; + } + } + else + { + return item->Value; + } +} +//--------------------------------------------------------------------------- +int __fastcall TDecompiler::AnalyzeConditions(int brType, DWORD curAdr, DWORD sAdr, DWORD jAdr, PLoopInfo loopInfo, BOOL bFloat) +{ + DWORD _curAdr = curAdr; + DWORD _begAdr, _bodyBegAdr, _bodyEndAdr, _jmpAdr = jAdr; + TDecompiler *de; + String _line; + + //simple if + if (brType == 0) + { + if (bFloat) SimulateFloatInstruction(sAdr); + if (CmpInfo.O == 'R')//not in + _line = "if (not (" + CmpInfo.L + " in " + CmpInfo.R + ")) then"; + else + _line = "if (" + CmpInfo.L + " " + GetInvertCondition(CmpInfo.O) + " " + CmpInfo.R + ") then"; + if (bFloat) SimulateFloatInstruction(sAdr); + + Env->AddToBody(_line); + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(CmpAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_begAdr, 0, loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("If->" + exception.Message); + } + Env->RestoreContext(_begAdr);//if (de->WasRet) + delete de; + } + //complex if + else if (brType == 1) + { + _bodyBegAdr = _curAdr; + if (!Env->GetBJLRange(sAdr, &_bodyBegAdr, &_bodyEndAdr, &_jmpAdr, loopInfo)) + { + Env->ErrAdr = _curAdr; + throw Exception("Control flow under construction"); + } + Env->CmpStack->Clear(); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_bodyBegAdr); + try + { + de->Decompile(sAdr, CF_BJL, loopInfo); + } + catch(Exception &exception) + { + delete de; + throw Exception("Complex if->" + exception.Message); + } + delete de; + + if (_bodyEndAdr > _bodyBegAdr) + { + Env->CreateBJLSequence(sAdr, _bodyBegAdr, _bodyEndAdr); + Env->BJLAnalyze(); + + _line = "if " + Env->PrintBJL() + " then"; + Env->AddToBody(_line); + Env->SaveContext(_bodyBegAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_bodyEndAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_bodyBegAdr, 0, loopInfo); + if (_jmpAdr && IsExit(_jmpAdr)) + { + Env->AddToBody("Exit;"); + } + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("Complex if->" + exception.Message); + } + Env->RestoreContext(_bodyBegAdr);//if (_jmpAdr || de->WasRet) + delete de; + + if (_jmpAdr) + { + if (!IsExit(_jmpAdr)) + { + Env->AddToBody("else"); + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_jmpAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_begAdr, CF_ELSE, loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("IfElse->" + exception.Message); + } + //Env->RestoreContext(_begAdr);//if (de->WasRet) + delete de; + } + } + } + else + { + Env->CreateBJLSequence(sAdr, _bodyBegAdr, _bodyEndAdr); + Env->BJLAnalyze(); + + _line = "if " + Env->PrintBJL() + " then"; + } + } + //cycle + else if (brType == 2) + { + if (bFloat) SimulateFloatInstruction(sAdr); + if (CmpInfo.O == 'R')//not in + _line = "if (not (" + CmpInfo.L + " in " + CmpInfo.R + ")) then"; + else + _line = "if (" + CmpInfo.L + " " + GetInvertCondition(CmpInfo.O) + " " + CmpInfo.R + ") then"; + Env->AddToBody(_line); + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(CmpAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_begAdr, 0, loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("If->" + exception.Message); + } + Env->RestoreContext(_begAdr);//if (de->WasRet) + delete de; + } + //simple if else + else if (brType == 3) + { + if (bFloat) SimulateFloatInstruction(sAdr); + if (CmpInfo.O == 'R')//not in + _line = "if (not (" + CmpInfo.L + " in " + CmpInfo.R + ")) then"; + else + _line = "if (" + CmpInfo.L + " " + GetInvertCondition(CmpInfo.O) + " " + CmpInfo.R + ") then"; + Env->AddToBody(_line); + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(CmpAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_begAdr, 0, loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("IfElse->" + exception.Message); + } + Env->RestoreContext(_begAdr); + delete de; + + Env->AddToBody("else"); + _begAdr = _curAdr; + Env->SaveContext(_begAdr); + de = new TDecompiler(Env); + de->SetStackPointers(this); + de->SetDeFlags(DeFlags); + de->SetStop(_jmpAdr); + try + { + Env->AddToBody("begin"); + _curAdr = de->Decompile(_begAdr, CF_ELSE, loopInfo); + Env->AddToBody("end"); + } + catch(Exception &exception) + { + delete de; + throw Exception("IfElse->" + exception.Message); + } + Env->RestoreContext(_begAdr);//if (de->WasRet) + delete de; + } + else + { + if (bFloat) SimulateFloatInstruction(sAdr); + _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Break;"; + Env->AddToBody(_line); + } + return _curAdr; +} +//--------------------------------------------------------------------------- +//cfLoc - make XRefs +//Names +//--------------------------------------------------------------------------- +//hints +//DynArrayClear == (varName := Nil); +//DynArraySetLength == SetLength(varName, colsnum, rowsnum) +//@Assign == AssignFile +//@Close == CloseFile +//@Flush == Flush +//@ResetFile;@ResetText == Reset +//@RewritFile4@RewritText == Rewrite +//@Str2Ext == Str(val:width:prec,s) +//@Write0LString == Write +//@WriteLn == WriteLn +//@LStrPos == Pos +//@LStrCopy == Copy +//@LStrLen == Length +//@LStrDelete == Delete +//@LStrInsert == Insert +//@LStrCmp == '=' +//@UStrCmp == '=' +//@RandInt == Random +//@LStrOfChar == StringOfChar +//0x61 = Ord('a') +//@LStrFromChar=Chr +//@LStrToPChar=PChar +//@LStrFromArray=String(src,len) +//--------------------------------------------------------------------------- +//Constructions +//--------------------------------------------------------------------------- +//Length +//test reg, reg +//jz @1 +//mov reg, [reg-4] +//or +//sub reg, 4 +//mov reg, [reg] +//--------------------------------------------------------------------------- +//mod 2 +//and eax, 80000001 +//jns @1 +//dec eax +//or eax, 0fffffffe +//inc eax +//@1 +//--------------------------------------------------------------------------- +//mod 2^k +//and eax, (80000000 | (2^k - 1)) +//jns @1 +//dec eax +//or eax, -2^k +//inc eax +//@1 +//--------------------------------------------------------------------------- +//div 2^k +//test reg, reg +//jns @1 +//add reg, (2^k - 1) +//sar reg, k +//@1 +//--------------------------------------------------------------------------- +//mod N +//mov reg, N (reg != eax) +//cdq +//idiv reg +//use edx +//--------------------------------------------------------------------------- +//in [0..N] +//sub eax, (N + 1) +//jb @body +//--------------------------------------------------------------------------- +//in [N1..N2,M1..M2] +//add eax, -N1 +//sub eax, (N2 - N1 + 1) +//jb @body +//add eax, -(M1 - N2 - 1) +//sub eax, (M1 - M2 + 1) +//jnb @end +//@body +//... +//@end +//--------------------------------------------------------------------------- +//not in [N1..N2,M1..M2] +//add eax, -N1 +//sub eax, (N2 - N1 + 1) +//jb @end +//add eax, -(M1 - N2 - 1) +//sub eax, (M1 - M2 + 1) +//jb @end +//@body +//... +//@end +//--------------------------------------------------------------------------- +//Int64 comparison if (A > B) then >(jbe,jle) >=(jb,jl) <(jae,jge) <=(ja,jg) +//cmp highA,highB +//jnz(jne) @1 +//{pop reg} +//{pop reg} +//cmp lowA,lowB +//jbe @2 (setnbe) +//jmp @3 +//@1: +//{pop reg} +//{pop reg} +//jle @2 (setnle) +//@3 +//body +//@2 +//--------------------------------------------------------------------------- +//LStrAddRef - if exists, then no prefix const +//--------------------------------------------------------------------------- +//Exit in except block +//@DoneExcept +//jmp ret +//@DoneExcept +//--------------------------------------------------------------------------- +//If array of strings before procedure (function), then this array is declared +//in var section +//--------------------------------------------------------------------------- +//mov [A],0 +//mov [A + 4], 0x3FF00000 +//->(Double)A := (00 00 00 00 00 00 F0 3F) Bytes in revers order! +//--------------------------------------------------------------------------- +//exetended -> tools +//push A +//push B +//push C +//C,B,A in reverse order +//--------------------------------------------------------------------------- +//@IsClass<-> (eax is edx) +//--------------------------------------------------------------------------- +//SE4(5D1817) - while!!! diff --git a/Decompiler.h b/Decompiler.h new file mode 100644 index 0000000..be993c4 --- /dev/null +++ b/Decompiler.h @@ -0,0 +1,320 @@ +//--------------------------------------------------------------------------- +#ifndef DecompilerH +#define DecompilerH + +#include "Main.h" +//--------------------------------------------------------------------------- +//Precedence of operations +#define PRECEDENCE_ATOM 24 +#define PRECEDENCE_UNARY 16 +#define PRECEDENCE_MULT 15 //*,/,div, mod,and,shl,shr,as +#define PRECEDENCE_ADD 14 //+,-,or,xor +#define PRECEDENCE_NOT 6 //@,not +#define PRECEDENCE_CMP 9 //=,<>,<,>,<=,>=,in,is +#define PRECEDENCE_NONE 0 + +#define TAB_SIZE 2 + +#define IF_ARG 1 +#define IF_VAR 2 +#define IF_STACK_PTR 4 +#define IF_CALL_RESULT 8 +#define IF_VMT_ADR 16 +#define IF_CYCLE_VAR 32 +#define IF_FIELD 64 +#define IF_ARRAY_PTR 128 +#define IF_INTVAL 256 +#define IF_INTERFACE 512 +#define IF_EXTERN_VAR 1024 //User for embedded procedures +#define IF_RECORD_FOFS 2048 //Offset inside record + +#define CF_CONSTRUCTOR 1 +#define CF_DESTRUCTOR 2 +#define CF_FINALLY 4 +#define CF_EXCEPT 8 +#define CF_LOOP 16 +#define CF_BJL 32 +#define CF_ELSE 64 + +#define CMP_FAILED 0 +#define CMP_BRANCH 1 +#define CMP_SET 2 + +//BJL +#define MAXSEQNUM 1024 + +#define BJL_USED -1 +#define BJL_EMPTY 0 +#define BJL_BRANCH 1 +#define BJL_JUMP 2 +#define BJL_LOC 3 +#define BJL_SKIP_BRANCH 4 //branches for IntOver, BoundErr,... + +typedef struct +{ + char state; //'U' not defined; 'B' branch; 'J' jump; '@' label; 'R' return; 'S' switch + int bcnt; //branches to... count + DWORD address; + String dExpr; //condition of direct expression + String iExpr; //condition of inverse expression + String result; +} TBJLInfo; + +typedef struct +{ + bool branch; + bool loc; + int type; + int address; + int idx; //IDX in BJLseq +} TBJL; +//BJL + +typedef struct +{ + String L; + char O; + String R; +} CMPITEM, *PCMPITEM; + +typedef struct +{ + BYTE Precedence; + int Size; //Size in bytes + int Offset; //Offset from beginning of type + DWORD IntValue; //For array element size calculation + DWORD Flags; + String Value; + String Value1; //For various purposes + String Type; + String Name; +} ITEM, *PITEM; + +typedef struct +{ + String Value; + String Name; +} WHAT, *PWHAT; + +#define itUNK 0 +#define itREG 1 +#define itLVAR 2 +#define itGVAR 3 + +typedef struct +{ + BYTE IdxType; + int IdxValue; + String IdxStr; +} IDXINFO, *PIDXINFO; + +class TForInfo +{ +public: + bool NoVar; + bool Down; //downto (=true) + int StopAdr; //instructions are ignored from this address and to end of cycle + String From; + String To; + IDXINFO VarInfo; + IDXINFO CntInfo; +public: + __fastcall TForInfo(bool ANoVar, bool ADown, int AStopAdr, String AFrom, String ATo, BYTE AVarType, int AVarIdx, BYTE ACntType, int ACntIdx); +}; + +typedef TForInfo *PForInfo; + +class TWhileInfo +{ +public: + bool NoCondition; //No condition +public: + __fastcall TWhileInfo(bool ANoCond); +}; + +typedef TWhileInfo *PWhileInfo; + +class TLoopInfo +{ +public: + BYTE Kind; //'F'- for; 'W' - while; 'T' - while true; 'R' - repeat + DWORD ContAdr; //Continue address + DWORD BreakAdr; //Break address + DWORD LastAdr; //Last address for decompilation (skip some last instructions) + PForInfo forInfo; + PWhileInfo whileInfo; +public: + __fastcall TLoopInfo(BYTE AKind, DWORD AContAdr, DWORD ABreakAdr, DWORD ALastAdr); + __fastcall ~TLoopInfo(); +}; + +typedef TLoopInfo *PLoopInfo; + +//cmpStack Format: "XYYYYYYY^ZZZZ" (== YYYYYY X ZZZZ) +//'A'-JO;'B'-JNO;'C'-JB;'D'-'JNB';'E'-JZ;'F'-JNZ;'G'-JBE;'H'-JA; +//'I'-'JS';'J'-JNS;'K'-JP;'L'-JNP;'M'-JL;'N'-JGE;'O'-JLE;'P'-JG + +//Only registers eax, ecx, edx, ebx, esp, ebp, esi, edi +typedef ITEM REGS[8]; + +class TNamer +{ +public: + int MaxIdx; + TStringList *Names; + __fastcall TNamer(); + __fastcall ~TNamer(); + String __fastcall MakeName(String shablon); +}; + +struct TCaseTreeNode; +struct TCaseTreeNode +{ + TCaseTreeNode *LNode; + TCaseTreeNode *RNode; + DWORD ZProc; + int FromVal; + int ToVal; +}; + +//structure for saving context of all registers +typedef struct +{ + DWORD adr; + REGS gregs; //general registers + REGS fregs; //float point registers + REGS fregsd; //float point registers (copy) +} DCONTEXT, *PDCONTEXT; + +class TDecompiler; + +class TDecompileEnv +{ +public: + String ProcName; //Name of decompiled procedure + DWORD StartAdr; //Start of decompilation area + int Size; //Size of decompilation area + int Indent; //For output source code + bool Alarm; + bool BpBased; + int LocBase; + DWORD StackSize; + PITEM Stack; + DWORD ErrAdr; + String LastResString; + TStringList *Body; + ITEM RegInfo[8]; + ITEM FStack[8]; //Floating registers stack + TNamer *Namer; + int BJLnum; + int BJLmaxbcnt; + TList *SavedContext; + TList *BJLseq;//TBJLInfo + TList *bjllist;//TBJL + TList *CmpStack; + bool Embedded; //Is proc embedded + TStringList *EmbeddedList; //List of embedded procedures addresses + + __fastcall TDecompileEnv(DWORD AStartAdr, int ASize, PInfoRec recN); + __fastcall ~TDecompileEnv(); + String __fastcall GetFieldName(PFIELDINFO fInfo); + String __fastcall GetArgName(PARGINFO argInfo); + String __fastcall GetGvarName(DWORD adr); + String __fastcall GetLvarName(int Ofs, String Type); + void __fastcall AssignItem(PITEM DstItem, PITEM SrcItem); + void __fastcall AddToBody(String src); + void __fastcall AddToBody(TStringList* src); + bool __fastcall IsExitAtBodyEnd(); + + void __fastcall OutputSourceCodeLine(String line); + void __fastcall OutputSourceCode(); + void __fastcall MakePrototype(); + void __fastcall DecompileProc(); + //BJL + bool __fastcall GetBJLRange(DWORD fromAdr, DWORD* bodyBegAdr, DWORD* bodyEndAdr, DWORD* jmpAdr, PLoopInfo loopInfo); + void __fastcall CreateBJLSequence(DWORD fromAdr, DWORD bodyBegAdr, DWORD bodyEndAdr); + void __fastcall UpdateBJLList(); + void __fastcall BJLAnalyze(); + bool __fastcall BJLGetIdx(int* idx, int from, int num); + bool __fastcall BJLCheckPattern1(char* t, int from); + bool __fastcall BJLCheckPattern2(char* t, int from); + int __fastcall BJLFindLabel(int address, int* no); + void __fastcall BJLSeqSetStateU(int* idx, int num); + void __fastcall BJLListSetUsed(int from, int num); + char __fastcall ExprGetOperation(String s); + void __fastcall ExprMerge(String& dst, String src, char op);//dst = dst op src, op = '|' or '&' + String __fastcall PrintBJL(); + PDCONTEXT __fastcall GetContext(DWORD Adr); + void __fastcall SaveContext(DWORD Adr); + void __fastcall RestoreContext(DWORD Adr); +}; + +class TDecompiler +{ +public: + bool WasRet; //Was ret instruction + char CmpOp; //Compare operation + DWORD CmpAdr; //Compare dest address + int _ESP_; //Stack pointer + int _TOP_; //Top of FStack + DISINFO DisInfo; + CMPITEM CmpInfo; + TDecompileEnv *Env; + BYTE *DeFlags; + PITEM Stack; + + __fastcall TDecompiler(TDecompileEnv* AEnv); + __fastcall ~TDecompiler(); + bool __fastcall CheckPrototype(PInfoRec ARec); + void __fastcall ClearStop(DWORD Adr); + DWORD __fastcall Decompile(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo); + DWORD __fastcall DecompileCaseEnum(DWORD fromAdr, int N, PLoopInfo loopInfo); + DWORD __fastcall DecompileGeneralCase(DWORD fromAdr, DWORD markAdr, PLoopInfo loopInfo, int N); + DWORD __fastcall DecompileTry(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo); + PITEM __fastcall FGet(int idx); + PITEM __fastcall FPop(); + void __fastcall FPush(PITEM val); + void __fastcall FSet(int idx, PITEM val); + void __fastcall FXch(int idx1, int idx2); + int __fastcall GetArrayFieldOffset(String ATypeName, int AFromOfs, int AScale, String& _name, String& _type); + int __fastcall GetCmpInfo(DWORD fromAdr); + String __fastcall GetCycleFrom(); + void __fastcall GetCycleIdx(PIDXINFO IdxInfo, DISINFO* ADisInfo); + String __fastcall GetCycleTo(); + void __fastcall GetFloatItemFromStack(int Esp, PITEM Dst, int FloatType); + void __fastcall GetInt64ItemFromStack(int Esp, PITEM Dst); + String __fastcall GetStringArgument(PITEM item); + PLoopInfo __fastcall GetLoopInfo(int fromAdr); + void __fastcall GetMemItem(int CurAdr, PITEM Dst, BYTE Op); + void __fastcall GetRegItem(int Idx, PITEM Dst); + String __fastcall GetRegType(int Idx); + String __fastcall GetSysCallAlias(String AName); + bool __fastcall Init(DWORD fromAdr); + void __fastcall InitFlags(); + void __fastcall MarkCaseEnum(DWORD fromAdr); + void __fastcall MarkGeneralCase(DWORD fromAdr); + PITEM __fastcall Pop(); + void __fastcall Push(PITEM item); + void __fastcall SetStackPointers(TDecompiler* ASrc); + void __fastcall SetDeFlags(BYTE* ASrc); + void __fastcall SetRegItem(int Idx, PITEM Val); + void __fastcall SetStop(DWORD Adr); + bool __fastcall SimulateCall(DWORD curAdr, DWORD callAdr, int instrLen, PMethodRec recM, DWORD AClassAdr); + void __fastcall SimulateFloatInstruction(DWORD curAdr); + void __fastcall SimulateFormatCall(); + void __fastcall SimulateInherited(DWORD procAdr); + void __fastcall SimulateInstr1(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr2(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr2RegImm(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr2RegMem(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr2RegReg(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr2MemImm(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr2MemReg(DWORD curAdr, BYTE Op); + void __fastcall SimulateInstr3(DWORD curAdr, BYTE Op); + void __fastcall SimulatePop(DWORD curAdr); + void __fastcall SimulatePush(DWORD curAdr, bool bShowComment); + bool __fastcall SimulateSysCall(String name, DWORD procAdr, int instrLen); + int __fastcall AnalyzeConditions(int brType, DWORD curAdr, DWORD sAdr, DWORD jAdr, PLoopInfo loopInfo, BOOL bFloat); +}; +//--------------------------------------------------------------------------- +#endif diff --git a/Sources/Libs/Disasm.cpp b/Disasm.cpp similarity index 96% rename from Sources/Libs/Disasm.cpp rename to Disasm.cpp index 8a17419..db81c91 100644 --- a/Sources/Libs/Disasm.cpp +++ b/Disasm.cpp @@ -1,1444 +1,1442 @@ -//--------------------------------------------------------------------------- -#include -#pragma hdrstop - -//--------------------------------------------------------------------------- -/* -#include -#include -#include -#include -#include -#include -*/ -#include "Disasm.h" -//--------------------------------------------------------------------------- -extern BYTE *Code; -extern int __fastcall Adr2Pos(DWORD Adr); -extern TCriticalSection* CrtSection; - -DWORD* (__stdcall* PdisNew)(int); -DWORD (_stdcall* CchFormatInstr)(char*, DWORD); -DWORD (_stdcall* Dist)(); -DWORD *DIS; -char* Reg8Tab[8] = -{ - //0 1 2 3 4 5 6 7 - "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" -}; -char* Reg16Tab[8] = -{ - //8 9 10 11 12 13 14 15 - "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" -}; -char* Reg32Tab[8] = -{ - //16 17 18 19 20 21 22 23 - "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" -}; -char* SegRegTab[8] = -{ - //24 25 26 27 28 29 30 31 - "es", "cs", "ss", "ds", "fs", "gs", "??", "??" -}; -char* RegCombTab[8] = -{ - "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" -}; -char* RepPrefixTab[4] = -{ - "lock", "repne", "repe", "rep" -}; -//--------------------------------------------------------------------------- -__fastcall MDisasm::MDisasm() -{ - hModule = 0; - PdisNew = 0; - CchFormatInstr = 0; - Dist = 0; - DIS = 0; -} -//--------------------------------------------------------------------------- -__fastcall MDisasm::~MDisasm() -{ - if (hModule) FreeLibrary(hModule); - hModule = 0; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::Init() -{ - hModule = LoadLibrary("dis.dll"); - if (!hModule) return 0; - PdisNew = (DWORD* (__stdcall*)(int))GetProcAddress(hModule, "?PdisNew@DIS@@SGPAV1@W4DIST@1@@Z"); - CchFormatInstr = (DWORD (_stdcall*)(char*, DWORD))GetProcAddress(hModule, "?CchFormatInstr@DIS@@QBEIPADI@Z"); - Dist = (DWORD (_stdcall*)())GetProcAddress(hModule, "?Dist@DIS@@QBE?AW4DIST@1@XZ"); - DIS = PdisNew(1); - return 1; -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetOp(char* mnem) -{ - DWORD dd = *((DWORD*)mnem); - - if ((dd & 0xFFFFFF) == 'vom') - { - if (mnem[3] == 0 || mnem[4] == 'x') return OP_MOV; - return OP_MOVS; - } - if (dd == 'hsup') return OP_PUSH; - if (dd == 'pop') return OP_POP; - if (dd == 'pmj') return OP_JMP; - if (dd == 'rox') return OP_XOR; - if (dd == 'pmc') return OP_CMP; - if (dd == 'tset') return OP_TEST; - if (dd == 'ael') return OP_LEA; - if (dd == 'dda') return OP_ADD; - if (dd == 'bus') return OP_SUB; - if (dd == 'ro') return OP_OR; - if (dd == 'dna') return OP_AND; - if (dd == 'cni') return OP_INC; - if (dd == 'ced') return OP_DEC; - if (dd == 'lum') return OP_MUL; - if (dd == 'vid') return OP_DIV; - if (dd == 'lumi') return OP_IMUL; - if (dd == 'vidi') return OP_IDIV; - if (dd == 'lhs' || dd == 'dlhs') return OP_SHL; - if (dd == 'rhs' || dd == 'drhs') return OP_SHR; - if (dd == 'las') return OP_SAL; - if (dd == 'ras') return OP_SAR; - if (dd == 'gen') return OP_NEG; - if (dd == 'ton') return OP_NOT; - if (dd == 'cda') return OP_ADC; - if (dd == 'bbs') return OP_SBB; - if (dd == 'qdc') return OP_CDQ; - if (dd == 'ghcx') return OP_XCHG; - if (dd == 'tb') return OP_BT; - if (dd == 'ctb') return OP_BTC; - if (dd == 'rtb') return OP_BTR; - if (dd == 'stb') return OP_BTS; - - if ((dd & 0xFFFFFF) == 'tes') return OP_SET; - - return OP_UNK; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::GetOpType(char* Op) -{ - char c = Op[0]; - if (c == 0) return otUND; - if (strchr(Op, '[')) return otMEM; - if (c >= '0' && c <= '9') return otIMM; - if (c == 's' && Op[1] == 't') return otFST; - return otREG; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::GetRegister(char* reg) -{ - for (int n = 0; n < 8; n++) - { - if (!stricmp(Reg32Tab[n], reg)) return n; - } - return -1; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::Disassemble(DWORD fromAdr, PDISINFO pDisInfo, char* disLine) -{ - int _res; - - CrtSection->Enter(); - - if (Adr2Pos(fromAdr)) - _res = Disassemble(Code + Adr2Pos(fromAdr), (__int64)fromAdr, pDisInfo, disLine); - else - _res = 0; - - CrtSection->Leave(); - return _res; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::Disassemble(BYTE* from, __int64 address, PDISINFO pDisInfo, char* disLine) -{ - int InstrLen, _res; - char *p, *q; - char Instr[1024]; - - CrtSection->Enter(); - - asm - { - push 64h - mov ecx, [DIS] - mov edx, [ecx] - push [from] - push dword ptr [address + 4] - push dword ptr [address] - call dword ptr [edx+18h] - mov [InstrLen], eax - } - - //If address of structure DISINFO not given, return only instruction length - if (pDisInfo) - { - if (InstrLen) - { - memset(pDisInfo, 0, sizeof(DISINFO)); - pDisInfo->OpRegIdx[0] = -1; - pDisInfo->OpRegIdx[1] = -1; - pDisInfo->OpRegIdx[2] = -1; - pDisInfo->BaseReg = -1; - pDisInfo->IndxReg = -1; - pDisInfo->RepPrefix = -1; - pDisInfo->SegPrefix = -1; - /* - asm - { - push 400h - lea eax, [Instr] - push eax - mov ecx, [DIS] - call CchFormatInstr - } - */ - FormatInstr(pDisInfo, disLine); - if (pDisInfo->IndxReg != -1 && !pDisInfo->Scale) pDisInfo->Scale = 1; - - DWORD dd = *((DWORD*)pDisInfo->Mnem); - - if (pDisInfo->Mnem[0] == 'f' || dd == 'tiaw') - { - pDisInfo->Float = true; - } - else if (pDisInfo->Mnem[0] == 'j') - { - pDisInfo->Branch = true; - if (pDisInfo->Mnem[1] != 'm') pDisInfo->Conditional = true; - } - else if (dd == 'llac') - { - pDisInfo->Call = true; - } - else if (dd == 'ter') - { - pDisInfo->Ret = true; - } - _res = InstrLen; - } - else - { - _res = 0; - } - } - else - { - _res = InstrLen; - } - - CrtSection->Leave(); - return _res; -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::FormatInstr(PDISINFO pDisInfo, char* disLine) -{ - BYTE _repPrefix, p, *OpName, *ArgInfo; - int i, Bytes = 0; - DWORD Cmd, Arg; - - if (disLine) *disLine = 0; - _repPrefix = GetRepPrefix(); - if (_repPrefix) - { - switch (_repPrefix) - { - case 0xF0: - if (disLine) strcat(disLine, "lock "); - pDisInfo->RepPrefix = 0; - Bytes = 5; - break; - case 0xF2: - if (disLine) strcat(disLine, "repne "); - pDisInfo->RepPrefix = 1; - Bytes = 6; - break; - case 0xF3: - if ((GetCop() & 0xF6) == 0xA6) - { - if (disLine) strcat(disLine, "repe "); - pDisInfo->RepPrefix = 2; - Bytes = 5; - } - else - { - if (disLine) strcat(disLine, "rep "); - pDisInfo->RepPrefix = 3; - Bytes = 4; - } - break; - } - } - - asm - { - mov ecx, [DIS] - mov edx, [ecx+4Ch] - mov eax, [edx] - mov [OpName], eax - } - - if (!GetOperandSize()) - { - switch (GetCop()) - { - case 0x60: - OpName = "pusha"; - break; - case 0x61: - OpName = "popa"; - break; - case 0x98: - OpName = "cbw"; - break; - case 0x99: - OpName = "cwd"; - break; - case 0x9C: - OpName = "pushf"; - break; - case 0x9D: - OpName = "popf"; - break; - case 0xCF: - OpName = "iret"; - break; - } - } - - if (!GetAddressSize() && GetCop() == 0xE3) OpName = "jcxz"; - - if (disLine) strcat(disLine, OpName); - strcpy(pDisInfo->Mnem, OpName); - Bytes += strlen(OpName); - - asm - { - mov ecx, [DIS] - mov edx, [ecx+4Ch] - mov eax, [edx+4] - add eax, 9 - mov [ArgInfo], eax - } - - for (i = 0; i < 3; i++) - { - if (!*ArgInfo) break; - if (disLine) - { - if (!i) - for (; Bytes < ASMMAXCOPLEN; Bytes++) strcat(disLine, " "); - else - strcat(disLine, ","); - } - 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 - } - - FormatArg(i, Cmd, Arg, pDisInfo, disLine); - pDisInfo->OpNum++; - } -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::OutputGeneralRegister(char *dst, int reg, int size) -{ -BYTE OperandSize; - - if (size == 1) - { - strcat(dst, Reg8Tab[reg]); - return 0; - } - - if (size == 2) - { - strcat(dst, Reg16Tab[reg]); - return 8; - } - - OperandSize = GetOperandSize(); - if (size != 4 && !OperandSize) - { - strcat(dst, Reg16Tab[reg]); - return 8; - } - - strcat(dst, Reg32Tab[reg]); - return 16; -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::OutputHex(char *dst, DWORD val) -{ - BYTE b; - char buf[12]; - - if (val <= 9) - { - sprintf(dst + strlen(dst), "%ld", val); - return; - } - sprintf(buf, "%lX", val); - b = buf[0]; - if (!isdigit(b)) strcat(dst, "0"); - strcat(dst, buf); -} -//--------------------------------------------------------------------------- -DWORD __fastcall MDisasm::GetAddress() -{ -int n; -DWORD res = 0; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+68h] - mov [n], eax - } - - switch (n) - { - case 0: - case 1: - case 2: - case 3: - case 7: - case 8: - case 9: - case 0x11: - asm - { - xor eax, eax - mov dword ptr [res], eax - } - break; - case 4: - case 0xA: - case 0xC: - case 0xD: - 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, 0FFFFh - and esi, 0 - @GA1: - mov eax, [ecx+8] - test eax, eax - jnz @GA2 - and ebx, 0FFFF0000h - and edi, 0FFFFh - 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 [res], eax - } - break; - case 5: - case 0xB: - case 0xE: - case 0xF: - 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, 0FFFFh - and esi, 0 - @GA5: - mov eax, [ecx+8] - test eax, eax - jnz @GA6 - and ebx, 0FFFF0000h - and edi, 0FFFFh - 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 [res], eax - } - break; - case 6: - case 0x10: - asm - { - mov edx, [ecx+64h] - mov eax, [edx+ecx+3Ch] - mov dword ptr [res], eax - } - break; - } - return res; -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::OutputSegPrefix(char* dst, PDISINFO pDisInfo) -{ - BYTE _segPrefix; - char *sptr = NULL; - - _segPrefix = GetSegPrefix(); - switch (_segPrefix) - { - case 0x26: - sptr = "es:"; - pDisInfo->SegPrefix = 0; - break; - case 0x2E: - sptr = "cs:"; - pDisInfo->SegPrefix = 1; - break; - case 0x36: - sptr = "ss:"; - pDisInfo->SegPrefix = 2; - break; - case 0x3E: - sptr = "ds:"; - pDisInfo->SegPrefix = 3; - break; - case 0x64: - sptr = "fs:"; - pDisInfo->SegPrefix = 4; - break; - case 0x65: - sptr = "gs:"; - pDisInfo->SegPrefix = 5; - break; - } - - if (sptr) strcat(dst, sptr); -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::EvaluateOperandSize() -{ - BYTE OperandSize; - DWORD Ofs; - int OpSize; - - OperandSize = GetOperandSize(); - asm - { - mov ecx, [DIS] - mov ecx, [ecx+4Ch] - mov ecx, [ecx+4] - mov [Ofs], ecx - } - - OpSize = (!OperandSize) ? 2: 4; - if (Ofs == 0x1041BB30 || //INVLPG, PREFETCH, PREFETCHW - Ofs == 0x1041C370) //LEA - return 0; - if (Ofs == 0x1041BC38) //BOUND - return 2*OpSize; - if (Ofs == 0x1041BCB0 || //CALL, JMP - Ofs == 0x1041C3E8) //LES, LDS, LSS, LFS, LGS - return OpSize + 2; - if (Ofs == 0x1041BC98 || //FLDENV - Ofs == 0x1041C460) //FNSTENV - return (!OperandSize) ? 14: 28; - if (Ofs == 0x1041BCF8 || //FRSTOR - Ofs == 0x1041C4C0) //FNSAVE - return (!OperandSize) ? 94: 108; - return OpSize; -} -//--------------------------------------------------------------------------- -char* __fastcall MDisasm::GetSizeString(int size) -{ - if (size == 1) return "byte"; - if (size == 2) return "word"; - if (size == 4) return "dword"; - if (size == 6) return "fword"; - if (size == 8) return "qword"; - if (size == 10) return "tbyte"; - return 0; -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::OutputSizePtr(int size, bool mm, PDISINFO pDisInfo, char* disLine) -{ - char* sptr = NULL; - - if (!size) size = EvaluateOperandSize(); - switch (size) - { - case 1: - sptr = "byte"; - break; - case 2: - sptr = "word"; - break; - case 4: - sptr = "dword"; - break; - case 6: - sptr = "fword"; - break; - case 8: - if (mm) - sptr = "mmword"; - else - sptr = "qword"; - break; - case 10: - sptr = "tbyte"; - break; - case 16: - if (mm) sptr = "xmmword"; - break; - } - if (sptr) - { - if (disLine) - { - strcat(disLine, sptr); - strcat(disLine, " ptr "); - } - pDisInfo->OpSize = size; - strcpy(pDisInfo->sSize, sptr); - } -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::OutputMemAdr32(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine) -{ - BYTE PostByte, SegPrefix, mod, *pos, sib, b; - bool ofs, ofs1, ib, mm; - int ss, index, base, idxofs, idxval; - DWORD offset32; - - asm - { - mov ecx, [DIS] - mov edx, [ecx+5Ch] - mov al, [edx+ecx+3Ch] - mov [PostByte], al - } - mod = PostByte & 0xC0; - if (mod == 0xC0) - { - if (!f1 && !f2) - { - idxval = PostByte & 7; - idxofs = OutputGeneralRegister(dst, idxval, arg); - pDisInfo->OpRegIdx[argno] = idxofs + idxval; - return; - } - if (f2) strcat(dst, "x"); - sprintf(dst + strlen(dst), "mm%d", PostByte & 7); - return; - } - ofs = false; - index = -1; - - asm - { - mov ecx, [DIS] - mov edx, [ecx+5Ch] - lea eax, [edx+ecx+3Dh] - mov [pos], eax - } - - base = PostByte & 7; - - if (base != 4) - { - if ((PostByte & 0xC7) == 5) //mod=00;r/m=101 - { - ofs = true; - base = -1; - } - } - else //sib - { - sib = *pos++; - if ((sib & 7) == 5 && !mod) - base = - 1; - else - base = sib & 7; - index = (sib >> 3) & 7; - if (index != 4) - ss = 1 << (sib >> 6); - else - index = -1; - if ((sib & 7) == 5 && !mod) - ofs = true; - } - - offset32 = 0; - if ((PostByte & 0xC0) == 0x40) //mod=01 - { - b = *pos; - offset32 = b; - if ((b & 0x80) != 0) - offset32 |= 0xFFFFFF00; - } - else if ((PostByte & 0xC0) == 0x80) //mod=10 - ofs = true; - - if (ofs) offset32 = *((DWORD*)pos); - - mm = (f1 || f2); - OutputSizePtr(arg, mm, pDisInfo, disLine); - OutputSegPrefix(dst, pDisInfo); - ib = (base != -1 || index != -1); - - if (!GetSegPrefix() && !ib) - { - pDisInfo->SegPrefix = 3; - strcat(dst, "ds:"); - } - strcat(dst, "["); - ofs1 = (offset32 != 0); - - if (ib) - { - if (base != -1) - { - strcat(dst, Reg32Tab[base]); - pDisInfo->BaseReg = base + 16; - } - if (index != -1) - { - if (base != -1) strcat(dst, "+"); - strcat(dst, Reg32Tab[index]); - pDisInfo->IndxReg = index + 16; - if (ss != 1) - { - sprintf(dst + strlen(dst), "*%d", ss); - pDisInfo->Scale = ss; - } - } - } - else - ofs1 = true; - - if (ofs) - { - pDisInfo->Offset = offset32; - if (ib) - { - if ((int)offset32 < 0) - { - strcat(dst, "-"); - offset32 = -(int)offset32; - } - else - strcat(dst, "+"); - } - OutputHex(dst, offset32); - strcat(dst, "]"); - return; - } - - if (ofs1) - { - pDisInfo->Offset = offset32; - if (ib) - { - if ((int)offset32 < 0) - { - strcat(dst, "-"); - offset32 = -(int)offset32; - } - else - strcat(dst, "+"); - } - OutputHex(dst, offset32); - } - strcat(dst, "]"); -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::OutputMemAdr16(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine) -{ - BYTE PostByte, SegPrefix, b; - bool ofs, mm; - char *regcomb, sign; - int idxofs, idxval; - DWORD offset16, dval; - - asm - { - mov ecx, [DIS] - mov edx, [ecx+5Ch] - mov al, [edx+ecx+3Ch] - mov [PostByte], al - } - if ((PostByte & 0xC0) == 0xC0) //mod=11 - { - if (!f1 && !f2) - { - idxval = PostByte & 7; - idxofs = OutputGeneralRegister(dst, idxval, arg); - pDisInfo->OpRegIdx[argno] = idxofs + idxval; - return; - } - if (f2) strcat(dst, "x"); - sprintf(dst + strlen(dst), "mm%d", PostByte & 7); - return; - } - - ofs = false; - regcomb = 0; - - if ((PostByte & 0xC7) == 6) //mod=00;r/m=110 - ofs = true; - else - { - b = PostByte & 7; - regcomb = RegCombTab[b]; - if (b == 0 || b == 1 || b == 7) - pDisInfo->BaseReg = 11; - if (b == 2 || b == 3 || b == 6) - pDisInfo->BaseReg = 13; - if (b == 0 || b == 2 || b == 4) - pDisInfo->IndxReg = 14; - if (b == 1 || b == 3 || b == 5) - pDisInfo->IndxReg = 15; - } - sign = 0; - - if ((PostByte & 0xC0) == 0x40) //mod=01 - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+5Ch] - mov al, [edx+ecx+3Dh] - test al, 80h - mov byte ptr [offset16], al - jnz @OM16_1 - mov eax, [offset16] - mov [sign], '+' - jmp @OM16_2 - @OM16_1: - mov [sign], '-' - neg eax - @OM16_2: - and eax, 0FFh - mov [offset16], eax - } - } - else if ((PostByte & 0xC0) == 0x80) //mod=10 - { - ofs = true; - } - - mm = (f1 || f2); - OutputSizePtr(arg, mm, pDisInfo, disLine); - OutputSegPrefix(dst, pDisInfo); - - if (!GetSegPrefix() && !regcomb) - { - strcat(dst, "ds:"); - pDisInfo->SegPrefix = 3; - } - strcat(dst, "["); - if (regcomb) strcat(dst, regcomb); - - if (ofs) - { - if (regcomb) strcat(dst, "+"); - asm - { - mov ecx, [DIS] - mov edx, [ecx+5Ch] - xor eax, eax - mov ax, [ecx+edx+3Dh] - mov [dval], eax - } - pDisInfo->Offset = dval; - sprintf(dst + strlen(dst), "%04lX]", dval); - return; - } - if (sign) - { - pDisInfo->Offset = offset16; - sprintf(dst + strlen(dst), "%c", sign); - OutputHex(dst, offset16); - strcat(dst, "]"); - } -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::FormatArg(int argno, DWORD cmd, DWORD arg, PDISINFO pDisInfo, char* disLine) -{ - BYTE AddressSize, OperandSize; - DWORD dval, adr; - int ival, idxofs, idxval, stno; - char Op[64], *p = Op; - - *p = 0; - - switch (cmd) - { - //segment:offset - case 1: - OperandSize = GetOperandSize(); - if (OperandSize) - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov ax, [edx+ecx+40h] - mov [dval], eax - } - p += sprintf(p, "%04lX:", dval); - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - mov eax, [edx+ecx+3Ch] - mov [dval], eax - } - sprintf(p, "%08lX", dval); - } - else - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov ax, [edx+ecx+3Eh] - mov [dval], eax - } - p += sprintf(p, "%04lX:", dval); - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov ax, [edx+ecx+3Ch] - mov [dval], eax - } - sprintf(p, "%04lX", dval); - } - break; - //cr# - case 2: - sprintf(Op, "cr%d", GetPostByteReg()); - break; - //Integer value (sar, shr) - case 3: - sprintf(Op, "%d", arg); - pDisInfo->Immediate = arg; - //pDisInfo->ImmPresent = true; - break; - //dr# - case 4: - sprintf(Op, "dr%d", GetPostByteReg()); - break; - //General register - case 5: - idxval = GetCop() & 7; - idxofs = OutputGeneralRegister(Op, idxval, arg); - pDisInfo->OpRegIdx[argno] = idxofs + idxval; - break; - //General register - case 6: - idxval = GetCop1() & 7; - idxofs = OutputGeneralRegister(Op, idxval, arg); - pDisInfo->OpRegIdx[argno] = idxofs + idxval; - break; - //Immediate byte - case 7: - if (GetCop() == 0x83) - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - movsx eax, byte ptr [edx+ecx+3Ch] - mov [dval], eax - } - } - else - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - movzx eax, byte ptr [edx+ecx+3Ch] - mov [dval], eax - } - } - pDisInfo->Immediate = dval; - //pDisInfo->ImmPresent = true; - //pDisInfo->ImmSize = 1; - OutputHex(Op, dval); - break; - //Immediate byte - case 8: - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov al, [edx+ecx+3Eh] - mov [dval], eax - } - pDisInfo->Immediate = dval; - //pDisInfo->ImmPresent = true; - //pDisInfo->ImmSize = 1; - OutputHex(Op, dval); - break; - //Immediate dword - case 9: - OperandSize = GetOperandSize(); - if (OperandSize) - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - mov eax, [edx+ecx+3Ch] - mov [dval], eax - } - } - else - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov ax, [edx+ecx+3Ch] - mov [dval], eax - } - } - pDisInfo->Immediate = dval; - //pDisInfo->ImmPresent = true; - //pDisInfo->ImmSize = 4; - OutputHex(Op, dval); - break; - //Immediate word (ret) - case 0xA: - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov ax, [edx+ecx+3Ch] - mov [dval], eax - } - pDisInfo->Immediate = dval; - //pDisInfo->ImmPresent = true; - //pDisInfo->ImmSize = 2; - OutputHex(Op, dval); - break; - //Address (jmp, jcond, call) - case 0xB: - case 0xC: - adr = GetAddress(); - pDisInfo->Immediate = adr; - //pDisInfo->ImmPresent = true; - sprintf(Op, "%08lX", adr); - break; - //Memory - case 0xD: - case 0xF: - case 0x1B: - AddressSize = GetAddressSize(); - if (AddressSize) - OutputMemAdr32(argno, Op, arg, (cmd == 0xD), (cmd == 0x1B), pDisInfo, disLine); - else - OutputMemAdr16(argno, Op, arg, (cmd == 0xD), (cmd == 0x1B), pDisInfo, disLine); - break; - //mm# - case 0xE: - sprintf(Op, "mm%d", GetPostByteReg()); - break; - //General register - case 0x10: - idxval = GetPostByteReg(); - idxofs = OutputGeneralRegister(Op, idxval, arg); - pDisInfo->OpRegIdx[argno] = idxofs + idxval; - break; - //Segment register - case 0x11: - idxval = GetPostByteReg(); - pDisInfo->OpRegIdx[argno] = idxval + 24; - sprintf(Op, "%s", SegRegTab[idxval]); - break; - //sreg:memory - case 0x12: - OutputSegPrefix(Op, pDisInfo); - AddressSize = GetAddressSize(); - if (AddressSize) - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - mov eax, [edx+ecx+3Ch] - mov [dval], eax - } - } - else - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - xor eax, eax - mov ax, [edx+ecx+3Ch] - mov [dval], eax - } - } - sprintf(Op + strlen(Op), "[%08lX]", dval); - pDisInfo->Offset = dval; //! - break; - //8-bit register - case 0x13: - strcpy(Op, Reg8Tab[arg]); - pDisInfo->OpRegIdx[argno] = arg; - break; - //General register - case 0x14: - idxval = arg; - idxofs = OutputGeneralRegister(Op, idxval, 0); - pDisInfo->OpRegIdx[argno] = idxofs + idxval; - break; - //8-bit register - case 0x15: - strcpy(Op, Reg8Tab[arg]); - pDisInfo->OpRegIdx[argno] = arg; - break; - //st - case 0x16: - strcpy(Op, "st"); - pDisInfo->OpRegIdx[argno] = 30; - break; - //st(#) - case 0x17: - stno = GetPostByteRm(); - sprintf(Op, "st(%d)", stno); - pDisInfo->OpRegIdx[argno] = stno + 30; - break; - //Segment register - case 0x18: - strcpy(Op, SegRegTab[arg]); - pDisInfo->OpRegIdx[argno] = arg + 24; - break; - //tr# - case 0x19: - sprintf(Op, "tr%d", GetPostByteReg()); - break; - //[esi] or [si] - case 0x1A: - OutputSizePtr(arg, false, pDisInfo, disLine); - OutputSegPrefix(Op, pDisInfo); - AddressSize = GetAddressSize(); - if (AddressSize) - { - pDisInfo->BaseReg = 22; - sprintf(Op + strlen(Op), "[%s]", "esi"); - } - else - { - pDisInfo->BaseReg = 14; - strcat(Op, "[si]"); - } - break; - //xmm# - case 0x1C: - sprintf(Op, "xmm%d", GetPostByteReg()); - break; - //[edi] or es:[di] - case 0x1D: - OutputSizePtr(arg, false, pDisInfo, disLine); - AddressSize = GetAddressSize(); - if (AddressSize) - { - pDisInfo->BaseReg = 23; - sprintf(Op, "[%s]", "edi"); - } - else - { - pDisInfo->SegPrefix = 0; - pDisInfo->BaseReg = 15; - strcpy(Op, "es:[di]"); - } - break; - //[ebx] or [bx] - case 0x1E: - OutputSizePtr(1, false, pDisInfo, disLine); - OutputSegPrefix(Op, pDisInfo); - AddressSize = GetAddressSize(); - if (AddressSize) - { - pDisInfo->BaseReg = 19; - sprintf(Op + strlen(Op), "[%s]", "ebx"); - } - else - { - pDisInfo->BaseReg = 11; - strcat(Op, "[bx]"); - } - break; - } - - if (argno == 0) - { - strcpy(pDisInfo->Op1, Op); - pDisInfo->OpType[0] = GetOpType(Op); - } - else if (argno == 1) - { - //strcpy(pDisInfo->Op2, Op); - pDisInfo->OpType[1] = GetOpType(Op); - } - else - { - //strcpy(pDisInfo->Op3, Op); - pDisInfo->OpType[2] = GetOpType(Op); - } - - if (disLine) strcat(disLine, Op); -} -//--------------------------------------------------------------------------- -bool __fastcall MDisasm::GetAddressSize() -{ -bool res; - - asm - { - mov ecx, [DIS] - mov al, [ecx+50h] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -bool __fastcall MDisasm::GetOperandSize() -{ -bool res; - - asm - { - mov ecx, [DIS] - mov al, [ecx+51h] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetSegPrefix() -{ -BYTE res; - - asm - { - mov ecx, [DIS] - mov al, [ecx+52h] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetRepPrefix() -{ -BYTE res; - - asm - { - mov ecx, [DIS] - mov al, [ecx+53h] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetCop() -{ -BYTE res; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+58h] - mov al, [eax+ecx+3Ch] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetCop1() -{ -BYTE res; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+58h] - mov al, [eax+ecx+3Dh] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetPostByte() -{ -BYTE res; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+5Ch] - mov al, [eax+ecx+3Ch] - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::SetPostByte(BYTE b) -{ - asm - { - mov ecx, [DIS] - mov edx, [ecx+5Ch] - mov al, [b] - mov [ecx+edx+3Ch], al - } -} -//--------------------------------------------------------------------------- -BYTE __fastcall MDisasm::GetPostByteMod() -{ -BYTE res; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+5Ch] - mov al, [eax+ecx+3Ch] - and al, 0C0h - mov [res], al - } - return res; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::GetPostByteReg() -{ -int res; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+5Ch] - mov al, [eax+ecx+3Ch] - shr eax, 3 - and eax, 7 - mov [res], eax - } - return res; -} -//--------------------------------------------------------------------------- -int __fastcall MDisasm::GetPostByteRm() -{ -int res; - - asm - { - mov ecx, [DIS] - mov eax, [ecx+5Ch] - mov al, [eax+ecx+3Ch] - and eax, 7 - mov [res], eax - } - return res; -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::SetOffset(DWORD ofs) -{ - BYTE AddressSize = GetAddressSize(); - if (AddressSize) - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - mov eax, [ofs] - mov [edx+ecx+3Ch], eax - } - } - else - { - asm - { - mov ecx, [DIS] - mov edx, [ecx+64h] - mov eax, [ofs] - mov [edx+ecx+3Ch], ax - } - } -} -//--------------------------------------------------------------------------- -void __fastcall MDisasm::GetInstrBytes(BYTE* dst) -{ - asm - { - mov ecx, [DIS] - lea esi, [ecx+3Ch] - mov edi, [dst] - mov ecx, [ecx+38h] - rep movsb - } -} -//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include "Disasm.h" +//--------------------------------------------------------------------------- +extern BYTE *Code; +extern int __fastcall Adr2Pos(DWORD Adr); +extern TCriticalSection* CrtSection; + +DWORD* (__stdcall* PdisNew)(int); +DWORD (_stdcall* CchFormatInstr)(char*, DWORD); +DWORD (_stdcall* Dist)(); +DWORD *DIS; +char* Reg8Tab[8] = +{ + //0 1 2 3 4 5 6 7 + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" +}; +char* Reg16Tab[8] = +{ + //8 9 10 11 12 13 14 15 + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" +}; +char* Reg32Tab[8] = +{ + //16 17 18 19 20 21 22 23 + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" +}; +char* SegRegTab[8] = +{ + //24 25 26 27 28 29 30 31 + "es", "cs", "ss", "ds", "fs", "gs", "??", "??" +}; +char* RegCombTab[8] = +{ + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" +}; +char* RepPrefixTab[4] = +{ + "lock", "repne", "repe", "rep" +}; +//--------------------------------------------------------------------------- +__fastcall MDisasm::MDisasm() +{ + hModule = 0; + PdisNew = 0; + CchFormatInstr = 0; + Dist = 0; + DIS = 0; +} +//--------------------------------------------------------------------------- +__fastcall MDisasm::~MDisasm() +{ + if (hModule) FreeLibrary(hModule); + hModule = 0; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::Init() +{ + hModule = LoadLibrary("dis.dll"); + if (!hModule) return 0; + PdisNew = (DWORD* (__stdcall*)(int))GetProcAddress(hModule, "?PdisNew@DIS@@SGPAV1@W4DIST@1@@Z"); + CchFormatInstr = (DWORD (_stdcall*)(char*, DWORD))GetProcAddress(hModule, "?CchFormatInstr@DIS@@QBEIPADI@Z"); + Dist = (DWORD (_stdcall*)())GetProcAddress(hModule, "?Dist@DIS@@QBE?AW4DIST@1@XZ"); + DIS = PdisNew(1); + return 1; +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetOp(char* mnem) +{ + DWORD dd = *((DWORD*)mnem); + + if ((dd & 0xFFFFFF) == 'vom') + { + if (mnem[3] == 0 || mnem[4] == 'x') return OP_MOV; + return OP_MOVS; + } + if (dd == 'hsup') return OP_PUSH; + if (dd == 'pop') return OP_POP; + if (dd == 'pmj') return OP_JMP; + if (dd == 'rox') return OP_XOR; + if (dd == 'pmc') return OP_CMP; + if (dd == 'tset') return OP_TEST; + if (dd == 'ael') return OP_LEA; + if (dd == 'dda') return OP_ADD; + if (dd == 'bus') return OP_SUB; + if (dd == 'ro') return OP_OR; + if (dd == 'dna') return OP_AND; + if (dd == 'cni') return OP_INC; + if (dd == 'ced') return OP_DEC; + if (dd == 'lum') return OP_MUL; + if (dd == 'vid') return OP_DIV; + if (dd == 'lumi') return OP_IMUL; + if (dd == 'vidi') return OP_IDIV; + if (dd == 'lhs' || dd == 'dlhs') return OP_SHL; + if (dd == 'rhs' || dd == 'drhs') return OP_SHR; + if (dd == 'las') return OP_SAL; + if (dd == 'ras') return OP_SAR; + if (dd == 'gen') return OP_NEG; + if (dd == 'ton') return OP_NOT; + if (dd == 'cda') return OP_ADC; + if (dd == 'bbs') return OP_SBB; + if (dd == 'qdc') return OP_CDQ; + if (dd == 'ghcx') return OP_XCHG; + if (dd == 'tb') return OP_BT; + if (dd == 'ctb') return OP_BTC; + if (dd == 'rtb') return OP_BTR; + if (dd == 'stb') return OP_BTS; + + if ((dd & 0xFFFFFF) == 'tes') return OP_SET; + + return OP_UNK; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::GetOpType(char* Op) +{ + char c = Op[0]; + if (c == 0) return otUND; + if (strchr(Op, '[')) return otMEM; + if (c >= '0' && c <= '9') return otIMM; + if (c == 's' && Op[1] == 't') return otFST; + return otREG; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::GetRegister(char* reg) +{ + for (int n = 0; n < 8; n++) + { + if (!stricmp(Reg32Tab[n], reg)) return n; + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::Disassemble(DWORD fromAdr, PDISINFO pDisInfo, char* disLine) +{ + int _res; + + CrtSection->Enter(); + + if (Adr2Pos(fromAdr)) + _res = Disassemble(Code + Adr2Pos(fromAdr), (__int64)fromAdr, pDisInfo, disLine); + else + _res = 0; + + CrtSection->Leave(); + return _res; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::Disassemble(BYTE* from, __int64 address, PDISINFO pDisInfo, char* disLine) +{ + int InstrLen, _res; + char *p, *q; + char Instr[1024]; + + CrtSection->Enter(); + + asm + { + push 64h + mov ecx, [DIS] + mov edx, [ecx] + push [from] + push dword ptr [address + 4] + push dword ptr [address] + call dword ptr [edx+18h] + mov [InstrLen], eax + } + + //If address of structure DISINFO not given, return only instruction length + if (pDisInfo) + { + if (InstrLen) + { + memset(pDisInfo, 0, sizeof(DISINFO)); + pDisInfo->OpRegIdx[0] = -1; + pDisInfo->OpRegIdx[1] = -1; + pDisInfo->OpRegIdx[2] = -1; + pDisInfo->BaseReg = -1; + pDisInfo->IndxReg = -1; + pDisInfo->RepPrefix = -1; + pDisInfo->SegPrefix = -1; + /* + asm + { + push 400h + lea eax, [Instr] + push eax + mov ecx, [DIS] + call CchFormatInstr + } + */ + FormatInstr(pDisInfo, disLine); + if (pDisInfo->IndxReg != -1 && !pDisInfo->Scale) pDisInfo->Scale = 1; + + DWORD dd = *((DWORD*)pDisInfo->Mnem); + + if (pDisInfo->Mnem[0] == 'f' || dd == 'tiaw') + { + pDisInfo->Float = true; + } + else if (pDisInfo->Mnem[0] == 'j') + { + pDisInfo->Branch = true; + if (pDisInfo->Mnem[1] != 'm') pDisInfo->Conditional = true; + } + else if (dd == 'llac') + { + pDisInfo->Call = true; + } + else if (dd == 'ter') + { + pDisInfo->Ret = true; + } + _res = InstrLen; + } + else + { + _res = 0; + } + } + else + { + _res = InstrLen; + } + + CrtSection->Leave(); + return _res; +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::FormatInstr(PDISINFO pDisInfo, char* disLine) +{ + BYTE _repPrefix, p, *OpName, *ArgInfo; + int i, Bytes = 0; + DWORD Cmd, Arg; + + if (disLine) *disLine = 0; + _repPrefix = GetRepPrefix(); + if (_repPrefix) + { + switch (_repPrefix) + { + case 0xF0: + if (disLine) strcat(disLine, "lock "); + pDisInfo->RepPrefix = 0; + Bytes = 5; + break; + case 0xF2: + if (disLine) strcat(disLine, "repne "); + pDisInfo->RepPrefix = 1; + Bytes = 6; + break; + case 0xF3: + if ((GetCop() & 0xF6) == 0xA6) + { + if (disLine) strcat(disLine, "repe "); + pDisInfo->RepPrefix = 2; + Bytes = 5; + } + else + { + if (disLine) strcat(disLine, "rep "); + pDisInfo->RepPrefix = 3; + Bytes = 4; + } + break; + } + } + + asm + { + mov ecx, [DIS] + mov edx, [ecx+4Ch] + mov eax, [edx] + mov [OpName], eax + } + + if (!GetOperandSize()) + { + switch (GetCop()) + { + case 0x60: + OpName = "pusha"; + break; + case 0x61: + OpName = "popa"; + break; + case 0x98: + OpName = "cbw"; + break; + case 0x99: + OpName = "cwd"; + break; + case 0x9C: + OpName = "pushf"; + break; + case 0x9D: + OpName = "popf"; + break; + case 0xCF: + OpName = "iret"; + break; + } + } + + if (!GetAddressSize() && GetCop() == 0xE3) OpName = "jcxz"; + + if (disLine) strcat(disLine, OpName); + strcpy(pDisInfo->Mnem, OpName); + Bytes += strlen(OpName); + + asm + { + mov ecx, [DIS] + mov edx, [ecx+4Ch] + mov eax, [edx+4] + add eax, 9 + mov [ArgInfo], eax + } + + for (i = 0; i < 3; i++) + { + if (!*ArgInfo) break; + if (disLine) + { + if (!i) + for (; Bytes < ASMMAXCOPLEN; Bytes++) strcat(disLine, " "); + else + strcat(disLine, ","); + } + 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 + } + + FormatArg(i, Cmd, Arg, pDisInfo, disLine); + pDisInfo->OpNum++; + } +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::OutputGeneralRegister(char *dst, int reg, int size) +{ +BYTE OperandSize; + + if (size == 1) + { + strcat(dst, Reg8Tab[reg]); + return 0; + } + + if (size == 2) + { + strcat(dst, Reg16Tab[reg]); + return 8; + } + + OperandSize = GetOperandSize(); + if (size != 4 && !OperandSize) + { + strcat(dst, Reg16Tab[reg]); + return 8; + } + + strcat(dst, Reg32Tab[reg]); + return 16; +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::OutputHex(char *dst, DWORD val) +{ + BYTE b; + char buf[12]; + + if (val <= 9) + { + sprintf(dst + strlen(dst), "%ld", val); + return; + } + sprintf(buf, "%lX", val); + b = buf[0]; + if (!isdigit(b)) strcat(dst, "0"); + strcat(dst, buf); +} +//--------------------------------------------------------------------------- +DWORD __fastcall MDisasm::GetAddress() +{ +int n; +DWORD res = 0; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+68h] + mov [n], eax + } + + switch (n) + { + case 0: + case 1: + case 2: + case 3: + case 7: + case 8: + case 9: + case 0x11: + asm + { + xor eax, eax + mov dword ptr [res], eax + } + break; + case 4: + case 0xA: + case 0xC: + case 0xD: + 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, 0FFFFh + and esi, 0 + @GA1: + mov eax, [ecx+8] + test eax, eax + jnz @GA2 + and ebx, 0FFFF0000h + and edi, 0FFFFh + 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 [res], eax + } + break; + case 5: + case 0xB: + case 0xE: + case 0xF: + 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, 0FFFFh + and esi, 0 + @GA5: + mov eax, [ecx+8] + test eax, eax + jnz @GA6 + and ebx, 0FFFF0000h + and edi, 0FFFFh + 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 [res], eax + } + break; + case 6: + case 0x10: + asm + { + mov edx, [ecx+64h] + mov eax, [edx+ecx+3Ch] + mov dword ptr [res], eax + } + break; + } + return res; +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::OutputSegPrefix(char* dst, PDISINFO pDisInfo) +{ + BYTE _segPrefix; + char *sptr = NULL; + + _segPrefix = GetSegPrefix(); + switch (_segPrefix) + { + case 0x26: + sptr = "es:"; + pDisInfo->SegPrefix = 0; + break; + case 0x2E: + sptr = "cs:"; + pDisInfo->SegPrefix = 1; + break; + case 0x36: + sptr = "ss:"; + pDisInfo->SegPrefix = 2; + break; + case 0x3E: + sptr = "ds:"; + pDisInfo->SegPrefix = 3; + break; + case 0x64: + sptr = "fs:"; + pDisInfo->SegPrefix = 4; + break; + case 0x65: + sptr = "gs:"; + pDisInfo->SegPrefix = 5; + break; + } + + if (sptr) strcat(dst, sptr); +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::EvaluateOperandSize() +{ + BYTE OperandSize; + DWORD Ofs; + int OpSize; + + OperandSize = GetOperandSize(); + asm + { + mov ecx, [DIS] + mov ecx, [ecx+4Ch] + mov ecx, [ecx+4] + mov [Ofs], ecx + } + + OpSize = (!OperandSize) ? 2: 4; + if (Ofs == 0x1041BB30 || //INVLPG, PREFETCH, PREFETCHW + Ofs == 0x1041C370) //LEA + return 0; + if (Ofs == 0x1041BC38) //BOUND + return 2*OpSize; + if (Ofs == 0x1041BCB0 || //CALL, JMP + Ofs == 0x1041C3E8) //LES, LDS, LSS, LFS, LGS + return OpSize + 2; + if (Ofs == 0x1041BC98 || //FLDENV + Ofs == 0x1041C460) //FNSTENV + return (!OperandSize) ? 14: 28; + if (Ofs == 0x1041BCF8 || //FRSTOR + Ofs == 0x1041C4C0) //FNSAVE + return (!OperandSize) ? 94: 108; + return OpSize; +} +//--------------------------------------------------------------------------- +char* __fastcall MDisasm::GetSizeString(int size) +{ + if (size == 1) return "byte"; + if (size == 2) return "word"; + if (size == 4) return "dword"; + if (size == 6) return "fword"; + if (size == 8) return "qword"; + if (size == 10) return "tbyte"; + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::OutputSizePtr(int size, bool mm, PDISINFO pDisInfo, char* disLine) +{ + char* sptr = NULL; + + if (!size) size = EvaluateOperandSize(); + switch (size) + { + case 1: + sptr = "byte"; + break; + case 2: + sptr = "word"; + break; + case 4: + sptr = "dword"; + break; + case 6: + sptr = "fword"; + break; + case 8: + if (mm) + sptr = "mmword"; + else + sptr = "qword"; + break; + case 10: + sptr = "tbyte"; + break; + case 16: + if (mm) sptr = "xmmword"; + break; + } + if (sptr) + { + if (disLine) + { + strcat(disLine, sptr); + strcat(disLine, " ptr "); + } + pDisInfo->OpSize = size; + strcpy(pDisInfo->sSize, sptr); + } +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::OutputMemAdr32(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine) +{ + BYTE PostByte, SegPrefix, mod, *pos, sib, b; + bool ofs, ofs1, ib, mm; + int ss, index, base, idxofs, idxval; + DWORD offset32; + + asm + { + mov ecx, [DIS] + mov edx, [ecx+5Ch] + mov al, [edx+ecx+3Ch] + mov [PostByte], al + } + mod = PostByte & 0xC0; + if (mod == 0xC0) + { + if (!f1 && !f2) + { + idxval = PostByte & 7; + idxofs = OutputGeneralRegister(dst, idxval, arg); + pDisInfo->OpRegIdx[argno] = idxofs + idxval; + return; + } + if (f2) strcat(dst, "x"); + sprintf(dst + strlen(dst), "mm%d", PostByte & 7); + return; + } + ofs = false; + index = -1; + + asm + { + mov ecx, [DIS] + mov edx, [ecx+5Ch] + lea eax, [edx+ecx+3Dh] + mov [pos], eax + } + + base = PostByte & 7; + + if (base != 4) + { + if ((PostByte & 0xC7) == 5) //mod=00;r/m=101 + { + ofs = true; + base = -1; + } + } + else //sib + { + sib = *pos++; + if ((sib & 7) == 5 && !mod) + base = - 1; + else + base = sib & 7; + index = (sib >> 3) & 7; + if (index != 4) + ss = 1 << (sib >> 6); + else + index = -1; + if ((sib & 7) == 5 && !mod) + ofs = true; + } + + offset32 = 0; + if ((PostByte & 0xC0) == 0x40) //mod=01 + { + b = *pos; + offset32 = b; + if ((b & 0x80) != 0) + offset32 |= 0xFFFFFF00; + } + else if ((PostByte & 0xC0) == 0x80) //mod=10 + ofs = true; + + if (ofs) offset32 = *((DWORD*)pos); + + mm = (f1 || f2); + OutputSizePtr(arg, mm, pDisInfo, disLine); + OutputSegPrefix(dst, pDisInfo); + ib = (base != -1 || index != -1); + + if (!GetSegPrefix() && !ib) + { + pDisInfo->SegPrefix = 3; + strcat(dst, "ds:"); + } + strcat(dst, "["); + ofs1 = (offset32 != 0); + + if (ib) + { + if (base != -1) + { + strcat(dst, Reg32Tab[base]); + pDisInfo->BaseReg = base + 16; + } + if (index != -1) + { + if (base != -1) strcat(dst, "+"); + strcat(dst, Reg32Tab[index]); + pDisInfo->IndxReg = index + 16; + if (ss != 1) + { + sprintf(dst + strlen(dst), "*%d", ss); + pDisInfo->Scale = ss; + } + } + } + else + ofs1 = true; + + if (ofs) + { + pDisInfo->Offset = offset32; + if (ib) + { + if ((int)offset32 < 0) + { + strcat(dst, "-"); + offset32 = -(int)offset32; + } + else + strcat(dst, "+"); + } + OutputHex(dst, offset32); + strcat(dst, "]"); + return; + } + + if (ofs1) + { + pDisInfo->Offset = offset32; + if (ib) + { + if ((int)offset32 < 0) + { + strcat(dst, "-"); + offset32 = -(int)offset32; + } + else + strcat(dst, "+"); + } + OutputHex(dst, offset32); + } + strcat(dst, "]"); +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::OutputMemAdr16(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine) +{ + BYTE PostByte, SegPrefix, b; + bool ofs, mm; + char *regcomb, sign; + int idxofs, idxval; + DWORD offset16, dval; + + asm + { + mov ecx, [DIS] + mov edx, [ecx+5Ch] + mov al, [edx+ecx+3Ch] + mov [PostByte], al + } + if ((PostByte & 0xC0) == 0xC0) //mod=11 + { + if (!f1 && !f2) + { + idxval = PostByte & 7; + idxofs = OutputGeneralRegister(dst, idxval, arg); + pDisInfo->OpRegIdx[argno] = idxofs + idxval; + return; + } + if (f2) strcat(dst, "x"); + sprintf(dst + strlen(dst), "mm%d", PostByte & 7); + return; + } + + ofs = false; + regcomb = 0; + + if ((PostByte & 0xC7) == 6) //mod=00;r/m=110 + ofs = true; + else + { + b = PostByte & 7; + regcomb = RegCombTab[b]; + if (b == 0 || b == 1 || b == 7) + pDisInfo->BaseReg = 11; + if (b == 2 || b == 3 || b == 6) + pDisInfo->BaseReg = 13; + if (b == 0 || b == 2 || b == 4) + pDisInfo->IndxReg = 14; + if (b == 1 || b == 3 || b == 5) + pDisInfo->IndxReg = 15; + } + sign = 0; + + if ((PostByte & 0xC0) == 0x40) //mod=01 + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+5Ch] + mov al, [edx+ecx+3Dh] + test al, 80h + mov byte ptr [offset16], al + jnz @OM16_1 + mov eax, [offset16] + mov [sign], '+' + jmp @OM16_2 + @OM16_1: + mov [sign], '-' + neg eax + @OM16_2: + and eax, 0FFh + mov [offset16], eax + } + } + else if ((PostByte & 0xC0) == 0x80) //mod=10 + { + ofs = true; + } + + mm = (f1 || f2); + OutputSizePtr(arg, mm, pDisInfo, disLine); + OutputSegPrefix(dst, pDisInfo); + + if (!GetSegPrefix() && !regcomb) + { + strcat(dst, "ds:"); + pDisInfo->SegPrefix = 3; + } + strcat(dst, "["); + if (regcomb) strcat(dst, regcomb); + + if (ofs) + { + if (regcomb) strcat(dst, "+"); + asm + { + mov ecx, [DIS] + mov edx, [ecx+5Ch] + xor eax, eax + mov ax, [ecx+edx+3Dh] + mov [dval], eax + } + pDisInfo->Offset = dval; + sprintf(dst + strlen(dst), "%04lX]", dval); + return; + } + if (sign) + { + pDisInfo->Offset = offset16; + sprintf(dst + strlen(dst), "%c", sign); + OutputHex(dst, offset16); + strcat(dst, "]"); + } +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::FormatArg(int argno, DWORD cmd, DWORD arg, PDISINFO pDisInfo, char* disLine) +{ + BYTE AddressSize, OperandSize; + DWORD dval, adr; + int ival, idxofs, idxval, stno; + char Op[64], *p = Op; + + *p = 0; + + switch (cmd) + { + //segment:offset + case 1: + OperandSize = GetOperandSize(); + if (OperandSize) + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov ax, [edx+ecx+40h] + mov [dval], eax + } + p += sprintf(p, "%04lX:", dval); + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + mov eax, [edx+ecx+3Ch] + mov [dval], eax + } + sprintf(p, "%08lX", dval); + } + else + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov ax, [edx+ecx+3Eh] + mov [dval], eax + } + p += sprintf(p, "%04lX:", dval); + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov ax, [edx+ecx+3Ch] + mov [dval], eax + } + sprintf(p, "%04lX", dval); + } + break; + //cr# + case 2: + sprintf(Op, "cr%d", GetPostByteReg()); + break; + //Integer value (sar, shr) + case 3: + sprintf(Op, "%d", arg); + pDisInfo->Immediate = arg; + //pDisInfo->ImmPresent = true; + break; + //dr# + case 4: + sprintf(Op, "dr%d", GetPostByteReg()); + break; + //General register + case 5: + idxval = GetCop() & 7; + idxofs = OutputGeneralRegister(Op, idxval, arg); + pDisInfo->OpRegIdx[argno] = idxofs + idxval; + break; + //General register + case 6: + idxval = GetCop1() & 7; + idxofs = OutputGeneralRegister(Op, idxval, arg); + pDisInfo->OpRegIdx[argno] = idxofs + idxval; + break; + //Immediate byte + case 7: + if (GetCop() == 0x83) + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + movsx eax, byte ptr [edx+ecx+3Ch] + mov [dval], eax + } + } + else + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + movzx eax, byte ptr [edx+ecx+3Ch] + mov [dval], eax + } + } + pDisInfo->Immediate = dval; + //pDisInfo->ImmPresent = true; + //pDisInfo->ImmSize = 1; + OutputHex(Op, dval); + break; + //Immediate byte + case 8: + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov al, [edx+ecx+3Eh] + mov [dval], eax + } + pDisInfo->Immediate = dval; + //pDisInfo->ImmPresent = true; + //pDisInfo->ImmSize = 1; + OutputHex(Op, dval); + break; + //Immediate dword + case 9: + OperandSize = GetOperandSize(); + if (OperandSize) + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + mov eax, [edx+ecx+3Ch] + mov [dval], eax + } + } + else + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov ax, [edx+ecx+3Ch] + mov [dval], eax + } + } + pDisInfo->Immediate = dval; + //pDisInfo->ImmPresent = true; + //pDisInfo->ImmSize = 4; + OutputHex(Op, dval); + break; + //Immediate word (ret) + case 0xA: + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov ax, [edx+ecx+3Ch] + mov [dval], eax + } + pDisInfo->Immediate = dval; + //pDisInfo->ImmPresent = true; + //pDisInfo->ImmSize = 2; + OutputHex(Op, dval); + break; + //Address (jmp, jcond, call) + case 0xB: + case 0xC: + adr = GetAddress(); + pDisInfo->Immediate = adr; + //pDisInfo->ImmPresent = true; + sprintf(Op, "%08lX", adr); + break; + //Memory + case 0xD: + case 0xF: + case 0x1B: + AddressSize = GetAddressSize(); + if (AddressSize) + OutputMemAdr32(argno, Op, arg, (cmd == 0xD), (cmd == 0x1B), pDisInfo, disLine); + else + OutputMemAdr16(argno, Op, arg, (cmd == 0xD), (cmd == 0x1B), pDisInfo, disLine); + break; + //mm# + case 0xE: + sprintf(Op, "mm%d", GetPostByteReg()); + break; + //General register + case 0x10: + idxval = GetPostByteReg(); + idxofs = OutputGeneralRegister(Op, idxval, arg); + pDisInfo->OpRegIdx[argno] = idxofs + idxval; + break; + //Segment register + case 0x11: + idxval = GetPostByteReg(); + pDisInfo->OpRegIdx[argno] = idxval + 24; + sprintf(Op, "%s", SegRegTab[idxval]); + break; + //sreg:memory + case 0x12: + OutputSegPrefix(Op, pDisInfo); + AddressSize = GetAddressSize(); + if (AddressSize) + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + mov eax, [edx+ecx+3Ch] + mov [dval], eax + } + } + else + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + xor eax, eax + mov ax, [edx+ecx+3Ch] + mov [dval], eax + } + } + sprintf(Op + strlen(Op), "[%08lX]", dval); + pDisInfo->Offset = dval; //! + break; + //8-bit register + case 0x13: + strcpy(Op, Reg8Tab[arg]); + pDisInfo->OpRegIdx[argno] = arg; + break; + //General register + case 0x14: + idxval = arg; + idxofs = OutputGeneralRegister(Op, idxval, 0); + pDisInfo->OpRegIdx[argno] = idxofs + idxval; + break; + //8-bit register + case 0x15: + strcpy(Op, Reg8Tab[arg]); + pDisInfo->OpRegIdx[argno] = arg; + break; + //st + case 0x16: + strcpy(Op, "st"); + pDisInfo->OpRegIdx[argno] = 30; + break; + //st(#) + case 0x17: + stno = GetPostByteRm(); + sprintf(Op, "st(%d)", stno); + pDisInfo->OpRegIdx[argno] = stno + 30; + break; + //Segment register + case 0x18: + strcpy(Op, SegRegTab[arg]); + pDisInfo->OpRegIdx[argno] = arg + 24; + break; + //tr# + case 0x19: + sprintf(Op, "tr%d", GetPostByteReg()); + break; + //[esi] or [si] + case 0x1A: + OutputSizePtr(arg, false, pDisInfo, disLine); + OutputSegPrefix(Op, pDisInfo); + AddressSize = GetAddressSize(); + if (AddressSize) + { + pDisInfo->BaseReg = 22; + sprintf(Op + strlen(Op), "[%s]", "esi"); + } + else + { + pDisInfo->BaseReg = 14; + strcat(Op, "[si]"); + } + break; + //xmm# + case 0x1C: + sprintf(Op, "xmm%d", GetPostByteReg()); + break; + //[edi] or es:[di] + case 0x1D: + OutputSizePtr(arg, false, pDisInfo, disLine); + AddressSize = GetAddressSize(); + if (AddressSize) + { + pDisInfo->BaseReg = 23; + sprintf(Op, "[%s]", "edi"); + } + else + { + pDisInfo->SegPrefix = 0; + pDisInfo->BaseReg = 15; + strcpy(Op, "es:[di]"); + } + break; + //[ebx] or [bx] + case 0x1E: + OutputSizePtr(1, false, pDisInfo, disLine); + OutputSegPrefix(Op, pDisInfo); + AddressSize = GetAddressSize(); + if (AddressSize) + { + pDisInfo->BaseReg = 19; + sprintf(Op + strlen(Op), "[%s]", "ebx"); + } + else + { + pDisInfo->BaseReg = 11; + strcat(Op, "[bx]"); + } + break; + } + + if (argno == 0) + { + strcpy(pDisInfo->Op1, Op); + pDisInfo->OpType[0] = GetOpType(Op); + } + else if (argno == 1) + { + //strcpy(pDisInfo->Op2, Op); + pDisInfo->OpType[1] = GetOpType(Op); + } + else + { + //strcpy(pDisInfo->Op3, Op); + pDisInfo->OpType[2] = GetOpType(Op); + } + + if (disLine) strcat(disLine, Op); +} +//--------------------------------------------------------------------------- +bool __fastcall MDisasm::GetAddressSize() +{ +bool res; + + asm + { + mov ecx, [DIS] + mov al, [ecx+50h] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +bool __fastcall MDisasm::GetOperandSize() +{ +bool res; + + asm + { + mov ecx, [DIS] + mov al, [ecx+51h] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetSegPrefix() +{ +BYTE res; + + asm + { + mov ecx, [DIS] + mov al, [ecx+52h] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetRepPrefix() +{ +BYTE res; + + asm + { + mov ecx, [DIS] + mov al, [ecx+53h] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetCop() +{ +BYTE res; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+58h] + mov al, [eax+ecx+3Ch] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetCop1() +{ +BYTE res; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+58h] + mov al, [eax+ecx+3Dh] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetPostByte() +{ +BYTE res; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+5Ch] + mov al, [eax+ecx+3Ch] + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::SetPostByte(BYTE b) +{ + asm + { + mov ecx, [DIS] + mov edx, [ecx+5Ch] + mov al, [b] + mov [ecx+edx+3Ch], al + } +} +//--------------------------------------------------------------------------- +BYTE __fastcall MDisasm::GetPostByteMod() +{ +BYTE res; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+5Ch] + mov al, [eax+ecx+3Ch] + and al, 0C0h + mov [res], al + } + return res; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::GetPostByteReg() +{ +int res; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+5Ch] + mov al, [eax+ecx+3Ch] + shr eax, 3 + and eax, 7 + mov [res], eax + } + return res; +} +//--------------------------------------------------------------------------- +int __fastcall MDisasm::GetPostByteRm() +{ +int res; + + asm + { + mov ecx, [DIS] + mov eax, [ecx+5Ch] + mov al, [eax+ecx+3Ch] + and eax, 7 + mov [res], eax + } + return res; +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::SetOffset(DWORD ofs) +{ + BYTE AddressSize = GetAddressSize(); + if (AddressSize) + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + mov eax, [ofs] + mov [edx+ecx+3Ch], eax + } + } + else + { + asm + { + mov ecx, [DIS] + mov edx, [ecx+64h] + mov eax, [ofs] + mov [edx+ecx+3Ch], ax + } + } +} +//--------------------------------------------------------------------------- +void __fastcall MDisasm::GetInstrBytes(BYTE* dst) +{ + asm + { + mov ecx, [DIS] + lea esi, [ecx+3Ch] + mov edi, [dst] + mov ecx, [ecx+38h] + rep movsb + } +} +//--------------------------------------------------------------------------- diff --git a/Disasm.h b/Disasm.h new file mode 100644 index 0000000..93fb92a --- /dev/null +++ b/Disasm.h @@ -0,0 +1,133 @@ +//--------------------------------------------------------------------------- +#ifndef DisasmH +#define DisasmH +//--------------------------------------------------------------------------- +#define ASMMAXCOPLEN 12 +//Instruction type +#define itUnknown 0 //Unknown instruction +#define itTransfer 1 //Data transfer instruction +#define itArifm 2 //Ariphmetical instruction +#define itLogic 3 //Logical instruction +#define itControl 4 //Control flow instruction +#define itString 5 //String instruction +#define itFloat 6 //Coprocessor instruction + +typedef struct +{ + char Mnem[32]; + char Op1[64]; + //char Op2[64]; + //char Op3[64]; + //BYTE InstrType; + bool Float; + bool Call; + bool Branch; + bool Conditional; + bool Ret; + //Register indexes, used as operands + int OpRegIdx[3]; + //[BaseReg + IndxReg*Scale + Offset] + int BaseReg; + int IndxReg; + int Scale; + DWORD Offset; + // + //bool ImmPresent; + DWORD Immediate; + BYTE OpSize;//Operand size + //BYTE ImmSize;//size of immediate operand + char sSize[32]; + int RepPrefix; + int SegPrefix; + BYTE OpNum; + BYTE OpType[3]; + //BYTE Op1Type; + //BYTE Op2Type; + //BYTE Op3Type; +} DISINFO, *PDISINFO; + +#define otUND 0 +#define otIMM 1 +#define otREG 2 +#define otMEM 3 +#define otFST 4 + +#define OP_RESET 0x80 +#define OP_A2 0x40 //2 or 3 operands + +#define OP_UNK 0 +#define OP_ADC 0x81 //1 OP_RESET +#define OP_ADD 0xC2 //2 OP_RESET OP_A2 +#define OP_AND 0xC3 //3 OP_RESET OP_A2 +#define OP_BT 0x44 //4 OP_A2 +#define OP_BTC 0x45 //5 OP_A2 +#define OP_BTR 0x46 //6 OP_A2 +#define OP_BTS 0x47 //7 OP_A2 +#define OP_CDQ 0x88 //8 OP_RESET +#define OP_CMP 0x49 //9 OP_A2 +#define OP_DEC 0x8A //A OP_RESET +#define OP_DIV 0x8B //B OP_RESET +#define OP_IDIV 0xCC //C OP_RESET OP_A2 +#define OP_IMUL 0xCD //D OP_RESET OP_A2 +#define OP_INC 0x8E //E OP_RESET +#define OP_JMP 0x8F //F OP_RESET +#define OP_LEA 0xD0 //10 OP_RESET OP_A2 +#define OP_MOV 0xD1 //11 OP_RESET OP_A2 +#define OP_MOVS 0x92 //12 OP_RESET +#define OP_MUL 0x93 //13 OP_RESET +#define OP_NEG 0x94 //14 OP_RESET +#define OP_OR 0xD5 //15 OP_RESET OP_A2 +#define OP_POP 0x96 //16 OP_RESET +#define OP_PUSH 0x97 //17 OP_RESET +#define OP_SAR 0x98 //18 OP_RESET +#define OP_SBB 0x99 //19 OP_RESET +#define OP_SET 0x9A //1A OP_RESET +#define OP_SUB 0x9B //1B OP_RESET +#define OP_TEST 0x5C //1C OP_A2 +#define OP_XCHG 0xDD //1D OP_RESET OP_A2 +#define OP_XOR 0xDE //1E OP_RESET OP_A2 +#define OP_SHR 0x9F //1F OP_RESET +#define OP_SAL 0xA0 //20 OP_RESET +#define OP_SHL 0xA1 //21 OP_RESET +#define OP_NOT 0xA2 //22 OP_RESET + +class MDisasm +{ +public: + __fastcall MDisasm(); + __fastcall ~MDisasm(); + int __fastcall Init(); + int __fastcall Disassemble(DWORD fromAdr, PDISINFO pDisInfo, char* disLine); + int __fastcall Disassemble(BYTE* from, __int64 address, PDISINFO pDisInfo, char* disLine); + int __fastcall GetRegister(char* reg); + HINSTANCE hModule; + BYTE __fastcall GetOp(char* mnem); + BYTE __fastcall GetCop(); + BYTE __fastcall GetCop1(); + BYTE __fastcall GetPostByte(); + void __fastcall SetPostByte(BYTE b); + void __fastcall SetOffset(DWORD ofs); + void __fastcall GetInstrBytes(BYTE* dst); + char* __fastcall GetSizeString(int size); +private: + bool __fastcall GetAddressSize(); + bool __fastcall GetOperandSize(); + BYTE __fastcall GetSegPrefix(); + BYTE __fastcall GetRepPrefix(); + BYTE __fastcall GetPostByteMod(); + int __fastcall GetPostByteReg(); + int __fastcall GetPostByteRm(); + int __fastcall GetOpType(char* Op); + void __fastcall FormatInstr(PDISINFO pDisInfo, char* disLine); + void __fastcall FormatArg(int argno, DWORD cmd, DWORD arg, PDISINFO pDisInfo, char* disLine); + int __fastcall OutputGeneralRegister(char *dst, int reg, int size); + void __fastcall OutputHex(char *dst, DWORD val); + DWORD __fastcall GetAddress(); + void __fastcall OutputSegPrefix(char* dst, PDISINFO pDisInfo); + int __fastcall EvaluateOperandSize(); + void __fastcall OutputSizePtr(int size, bool mm, PDISINFO pDisInfo, char* disLine); + void __fastcall OutputMemAdr16(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine); + void __fastcall OutputMemAdr32(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine); +}; +//--------------------------------------------------------------------------- +#endif diff --git a/EditFieldsDlg.cpp b/EditFieldsDlg.cpp new file mode 100644 index 0000000..068beec --- /dev/null +++ b/EditFieldsDlg.cpp @@ -0,0 +1,284 @@ +//---------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Misc.h" +#include "EditFieldsDlg.h" +#include "Main.h" +//---------------------------------------------------------------------------- +#pragma resource "*.dfm" + +extern bool ProjectModified; +extern DWORD CurProcAdr; +extern DWORD CodeBase; +extern DWORD *Flags; +extern PInfoRec *Infos; + +TFEditFieldsDlg_11011981 *FEditFieldsDlg_11011981; +//---------------------------------------------------------------------------- +__fastcall TFEditFieldsDlg_11011981::TFEditFieldsDlg_11011981(TComponent *Owner) + : TForm(Owner) +{ + Op = FD_OP_EDIT; + SelIndex = -1; + FieldOffset = -1; + VmtAdr = 0; + fieldsList = new TList; +} +//---------------------------------------------------------------------------- +__fastcall TFEditFieldsDlg_11011981::~TFEditFieldsDlg_11011981() +{ + if (fieldsList) delete fieldsList; +} +//---------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::ShowFields() +{ + lbFields->Enabled = true; + lbFields->Clear(); + fieldsList->Clear(); + int fieldsNum = FMain_11011981->LoadFieldTable(VmtAdr, fieldsList); + if (fieldsNum) + { + SelIndex = -1; + for (int n = 0; n < fieldsNum; n++) + { + PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[n]; + String line = Val2Str5(fInfo->Offset) + " "; + if (fInfo->Name != "") + line += fInfo->Name; + else + line += "?"; + line += ":"; + if (fInfo->Type != "") + line += fInfo->Type; + else + line += "?"; + lbFields->Items->Add(line); + if (fInfo->Offset == FieldOffset) + SelIndex = n; + } + } +} +//---------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::FormShow(TObject *Sender) +{ + Caption = GetClsName(VmtAdr) + " fields"; + + edtPanel->Visible = false; + lbFields->Height = lbFXrefs->Height; + + lbFXrefs->Clear(); + ShowFields(); + lbFields->ItemIndex = SelIndex; + + bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); + bAdd->Enabled = true; + bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); + bClose->Enabled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::lbFXrefsDblClick(TObject *Sender) +{ + char type[2]; + DWORD adr; + + String item = lbFXrefs->Items->Strings[lbFXrefs->ItemIndex]; + sscanf(item.c_str() + 1, "%lX%2c", &adr, type); + + for (int m = Adr2Pos(adr); m >= 0; m--) + { + if (IsFlagSet(cfProcStart, m)) + { + FMain_11011981->ShowCode(Pos2Adr(m), adr, -1, -1); + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::lbFieldsClick(TObject *Sender) +{ + lbFXrefs->Clear(); + + if (lbFields->ItemIndex == -1) return; + + String line; + PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; + if (fInfo->xrefs) + { + for (int n = 0; n < fInfo->xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)fInfo->xrefs->Items[n]; + line = Val2Str8(recX->adr + recX->offset); + if (recX->type == 'c') line += " <-"; + lbFXrefs->Items->Add(line); + } + } + bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); + bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::bEditClick(TObject *Sender) +{ + Op = FD_OP_EDIT; + lbFields->Height = lbFXrefs->Height - edtPanel->Height; + edtPanel->Visible = true; + + PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; + edtOffset->Text = Val2Str0(fInfo->Offset); + edtOffset->Enabled = false; + edtName->Text = fInfo->Name; + edtName->Enabled = true; + edtType->Text = fInfo->Type; + edtType->Enabled = true; + edtName->SetFocus(); + + lbFields->Enabled = false; + bApply->Enabled = false; + bClose->Enabled = true; + bEdit->Enabled = false; + bAdd->Enabled = false; + bRemove->Enabled = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::edtNameChange(TObject *Sender) +{ + bApply->Enabled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::edtTypeChange(TObject *Sender) +{ + bApply->Enabled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::bApplyClick(TObject *Sender) +{ + bool vmt, ok = false; + DWORD adr; + int n, size, offset, fromOfs, toOfs; + PInfoRec recN; + PFIELDINFO fInfo; + String rtti; + + recN = GetInfoRec(VmtAdr); + switch (Op) + { + case FD_OP_EDIT: + fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; + fInfo->Name = Trim(edtName->Text); + fInfo->Type = Trim(edtType->Text); + //Delete all fields (if exists) that covered by new type + fromOfs = fInfo->Offset; + if (GetTypeKind(edtType->Text, &size) == ikRecord) + { + toOfs = fromOfs + size; + for (n = 0; n < fieldsList->Count; n++) + { + fInfo = (PFIELDINFO)fieldsList->Items[n]; + offset = fInfo->Offset; + if (offset > fromOfs && offset < toOfs) + { + recN->vmtInfo->RemoveField(offset); + } + } + } + break; + case FD_OP_ADD: + case FD_OP_DELETE: + sscanf(edtOffset->Text.Trim().c_str(), "%lX", &offset); + if (Op == FD_OP_ADD) + { + fInfo = FMain_11011981->GetField(recN->GetName(), offset, &vmt, &adr, ""); + if (!fInfo || Application->MessageBox("Field already exists", "Replace?", MB_YESNO) == IDYES) + recN->vmtInfo->AddField(0, 0, FIELD_PUBLIC, offset, -1, Trim(edtName->Text), Trim(edtType->Text)); + if (fInfo && fInfo->Scope == SCOPE_TMP) + delete fInfo; + } + if (Op == FD_OP_DELETE) + { + if (Application->MessageBox("Delete field?", "Confirmation", MB_YESNO) == IDYES) + recN->vmtInfo->RemoveField(offset); + } + break; + } + int itemidx = lbFields->ItemIndex; + int topidx = lbFields->TopIndex; + ShowFields(); + lbFields->ItemIndex = itemidx; + lbFields->TopIndex = topidx; + + FMain_11011981->RedrawCode(); + FMain_11011981->ShowClassViewer(VmtAdr); + + edtPanel->Visible = false; + lbFields->Height = lbFXrefs->Height; + + lbFields->Enabled = true; + bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); + bAdd->Enabled = true; + bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); + + ProjectModified = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::bCloseClick( + TObject *Sender) +{ + edtPanel->Visible = false; + lbFields->Height = lbFXrefs->Height; + + lbFields->Enabled = true; + bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); + bAdd->Enabled = true; + bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::bAddClick(TObject *Sender) +{ + Op = FD_OP_ADD; + lbFields->Height = lbFXrefs->Height - edtPanel->Height; + edtPanel->Visible = true; + + edtOffset->Text = ""; + edtOffset->Enabled = true; + edtName->Text = ""; + edtName->Enabled = true; + edtType->Text = ""; + edtType->Enabled = true; + edtOffset->SetFocus(); + + lbFields->Enabled = false; + bApply->Enabled = false; + bClose->Enabled = true; + bEdit->Enabled = false; + bAdd->Enabled = false; + bRemove->Enabled = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::bRemoveClick(TObject *Sender) +{ + Op = FD_OP_DELETE; + lbFields->Height = lbFXrefs->Height - edtPanel->Height; + edtPanel->Visible = true; + + PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; + edtOffset->Text = Val2Str0(fInfo->Offset); + edtOffset->Enabled = false; + edtName->Text = fInfo->Name; + edtName->Enabled = false; + edtType->Text = fInfo->Type; + edtType->Enabled = false; + + lbFields->Enabled = false; + bApply->Enabled = true; + bClose->Enabled = true; + bEdit->Enabled = false; + bAdd->Enabled = false; + bRemove->Enabled = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFieldsDlg_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/EditFieldsDlg.dfm b/EditFieldsDlg.dfm similarity index 83% rename from Sources/Forms/EditFieldsDlg.dfm rename to EditFieldsDlg.dfm index 8946c88..bef42ba 100644 Binary files a/Sources/Forms/EditFieldsDlg.dfm and b/EditFieldsDlg.dfm differ diff --git a/EditFieldsDlg.h b/EditFieldsDlg.h new file mode 100644 index 0000000..c9cf31b --- /dev/null +++ b/EditFieldsDlg.h @@ -0,0 +1,60 @@ +//---------------------------------------------------------------------------- +#ifndef EditFieldsDlgH +#define EditFieldsDlgH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +#define FD_OP_EDIT 0 +#define FD_OP_ADD 1 +#define FD_OP_DELETE 2 + +class TFEditFieldsDlg_11011981 : public TForm +{ +__published: + TListBox *lbFXrefs; + TListBox *lbFields; + TPanel *Panel1; + TButton *bAdd; + TButton *bRemove; + TPanel *edtPanel; + TLabeledEdit *edtName; + TLabeledEdit *edtType; + TButton *bApply; + TButton *bClose; + TLabeledEdit *edtOffset; + TButton *bEdit; + void __fastcall FormShow(TObject *Sender); + void __fastcall lbFXrefsDblClick(TObject *Sender); + void __fastcall lbFieldsClick(TObject *Sender); + void __fastcall edtNameChange(TObject *Sender); + void __fastcall edtTypeChange(TObject *Sender); + void __fastcall bCloseClick(TObject *Sender); + void __fastcall bApplyClick(TObject *Sender); + void __fastcall bEditClick(TObject *Sender); + void __fastcall bRemoveClick(TObject *Sender); + void __fastcall bAddClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: + void __fastcall ShowFields(); +public: + BYTE Op; + int SelIndex; + int FieldOffset; + DWORD VmtAdr; + TList *fieldsList; + virtual __fastcall TFEditFieldsDlg_11011981(TComponent *Owner); + virtual __fastcall ~TFEditFieldsDlg_11011981(); +}; +//---------------------------------------------------------------------------- +extern TFEditFieldsDlg_11011981 *FEditFieldsDlg_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/EditFunctionDlg.cpp b/EditFunctionDlg.cpp new file mode 100644 index 0000000..fd0e8c9 --- /dev/null +++ b/EditFunctionDlg.cpp @@ -0,0 +1,794 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Misc.h" +#include "EditFunctionDlg.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" + +extern bool ProjectModified; +extern DWORD CodeBase; +extern PInfoRec *Infos; +extern DWORD *Flags; +extern TList *VmtList; +extern char StringBuf[MAXSTRBUFFER]; +extern MKnowledgeBase KnowledgeBase; + +TFEditFunctionDlg_11011981 *FEditFunctionDlg_11011981; +//--------------------------------------------------------------------- +__fastcall TFEditFunctionDlg_11011981::TFEditFunctionDlg_11011981(TComponent* AOwner) + : TForm(AOwner) +{ + VmtCandidatesNum = 0; +} +//--------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bOkClick(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FormKeyDown(TObject *Sender, + WORD &Key, TShiftState Shift) +{ + if (Key == VK_ESCAPE) ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FormShow(TObject *Sender) +{ + PInfoRec recN = GetInfoRec(Adr); + SFlags = recN->procInfo->flags; + SName = recN->GetName(); + EndAdr = Adr + recN->procInfo->procSize - 1; + lEndAdr->Text = Val2Str0(EndAdr); + StackSize = recN->procInfo->stackSize; + lStackSize->Text = Val2Str0(StackSize); + + FillVMTCandidates(); + pc->ActivePage = tsType; + //Type + cbMethod->Enabled = false; + cbVmtCandidates->Enabled = false; + mType->Enabled = false; + + cbEmbedded->Enabled = false; + lEndAdr->Enabled = false; + lStackSize->Enabled = false; + rgFunctionKind->Enabled = false; + rgCallKind->Enabled = false; + bApplyType->Enabled = false; + bCancelType->Enabled = false; + FillType(); + //Args + lbArgs->Enabled = true; + FillArgs(); + //Vars + lbVars->Enabled = true; + pnlVars->Visible = false; + edtVarOfs->Text = ""; + edtVarSize->Text = ""; + edtVarName->Text = ""; + edtVarType->Text = ""; + FillVars(); + //Buttons + bEdit->Enabled = true; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + bOk->Enabled = false; + + TypModified = false; + VarModified = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bEditClick(TObject *Sender) +{ + if (pc->ActivePage == tsType) + { + cbMethod->Enabled = true; + cbVmtCandidates->Enabled = true; + mType->Enabled = true; + cbEmbedded->Enabled = true; + lEndAdr->Enabled = true; + lStackSize->Enabled = true; + rgFunctionKind->Enabled = true; + rgCallKind->Enabled = true; + bApplyType->Enabled = true; + bCancelType->Enabled = true; + } + else if (pc->ActivePage == tsVars) + { + edtVarOfs->Text = ""; + edtVarName->Text = ""; + edtVarType->Text = ""; + + PInfoRec recN = GetInfoRec(Adr); + PLOCALINFO locInfo = PLOCALINFO(recN->procInfo->locals->Items[lbVars->ItemIndex]); + if (locInfo) + { + edtVarOfs->Text = IntToHex((int)locInfo->Ofs, 0); + edtVarSize->Text = String(locInfo->Size); + edtVarName->Text = String(locInfo->Name); + edtVarType->Text = String(locInfo->TypeDef); + } + + lbVars->Height = pc->Height - pnlVars->Height; + pnlVars->Visible = true; + } + + lbArgs->Enabled = false; + lbVars->Enabled = false; + //Buttons + bEdit->Enabled = false; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::lbVarsClick(TObject *Sender) +{ + bEdit->Enabled = (lbVars->SelCount == 1); + bRemoveSelected->Enabled = (lbVars->SelCount > 0); + bRemoveAll->Enabled = (lbVars->Count > 0); +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::pcChange(TObject *Sender) +{ + if (pc->ActivePage == tsType) + { + bEdit->Enabled = true; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + } + else if (pc->ActivePage == tsArgs) + { + bEdit->Enabled = false; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + return; + } + else + { + bAdd->Enabled = false; + if (lbVars->Count > 0) + { + bEdit->Enabled = (lbVars->SelCount == 1); + bRemoveSelected->Enabled = (lbVars->SelCount > 0); + bRemoveAll->Enabled = (lbVars->Count > 0); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bApplyTypeClick(TObject *Sender) +{ + if (cbMethod->Checked && cbVmtCandidates->Text == "") + { + ShowMessage("Class name is empty"); + return; + } + + DWORD newEndAdr; + if (lEndAdr->Text == "" || !TryStrToInt(String("$") + lEndAdr->Text, newEndAdr)) + { + ShowMessage("End address is not valid"); + return; + } + newEndAdr = StrToInt(String("$") + lEndAdr->Text); + if (!IsValidCodeAdr(newEndAdr)) + { + ShowMessage("End address is not valid"); + return; + } + + if (lStackSize->Text == "" || !TryStrToInt(String("$") + lStackSize->Text, StackSize)) + { + ShowMessage("StackSize not valid"); + return; + } + StackSize = StrToInt(String("$") + lStackSize->Text); + + PInfoRec recN = GetInfoRec(Adr); + //Set new procSize + recN->procInfo->procSize = newEndAdr - Adr + 1; + + switch (rgFunctionKind->ItemIndex) + { + case 0: + recN->kind = ikConstructor; + break; + case 1: + recN->kind = ikDestructor; + break; + case 2: + recN->kind = ikProc; + recN->type = ""; + break; + case 3: + recN->kind = ikFunc; + break; + } + + recN->procInfo->flags &= 0xFFFFFFF8; + recN->procInfo->flags |= rgCallKind->ItemIndex; + + if (cbEmbedded->Checked) + recN->procInfo->flags |= PF_EMBED; + else + recN->procInfo->flags &= ~PF_EMBED; + + String line, decl = ""; + for (int n = 0; n < mType->Lines->Count; n++) + { + line = mType->Lines->Strings[n].Trim(); + if (line == "") continue; + decl += line; + } + + decl = decl.Trim(); + char* p = decl.AnsiLastChar(); + if (*p == ';') *p = ' '; + p = decl.c_str(); + String name = ""; + for (int len = 0;; len++) + { + char c = *p; + if (!c || c == ' ' || c == '(' || c == ';' || c == ':') + { + *p = 0; + name = decl.SubString(1, len); + *p = c; + break; + } + p++; + } + + if (recN->kind == ikConstructor) + { + recN->SetName(cbVmtCandidates->Text + ".Create"); + } + else if (recN->kind == ikDestructor) + { + recN->SetName(cbVmtCandidates->Text + ".Destroy"); + } + else if (SameText(name, GetDefaultProcName(Adr))) + { + if (cbMethod->Checked && (recN->procInfo->flags & PF_ALLMETHODS)) + recN->SetName(cbVmtCandidates->Text + "." + name); + else + recN->SetName(""); + } + else + { + if (cbMethod->Checked && (recN->procInfo->flags & PF_ALLMETHODS)) + recN->SetName(cbVmtCandidates->Text + "." + ExtractProcName(name)); + else + recN->SetName(name); + } + + recN->procInfo->DeleteArgs(); + int from = 0; + if (recN->kind == ikConstructor || recN->kind == ikDestructor) + { + recN->procInfo->AddArg(0x21, 0, 4, "Self", cbVmtCandidates->Text); + recN->procInfo->AddArg(0x21, 1, 4, "_Dv__", "Boolean"); + from = 2; + } + else if (recN->procInfo->flags & PF_ALLMETHODS) + { + recN->procInfo->AddArg(0x21, 0, 4, "Self", cbVmtCandidates->Text); + from = 1; + } + String retType = recN->procInfo->AddArgsFromDeclaration(p, from, rgCallKind->ItemIndex); + + if (recN->kind == ikFunc) recN->type = retType; + + recN->procInfo->stackSize = StackSize; + + FillType(); + FillArgs(); + + cbMethod->Enabled = false; + mType->Enabled = false; + cbEmbedded->Enabled = false; + lEndAdr->Enabled = false; + lStackSize->Enabled = false; + rgFunctionKind->Enabled = false; + rgCallKind->Enabled = false; + bApplyType->Enabled = false; + bCancelType->Enabled = false; + //Buttons + bEdit->Enabled = true; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + bOk->Enabled = true; + + TypModified = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bCancelTypeClick( + TObject *Sender) +{ + if (!TypModified) + { + PInfoRec recN = GetInfoRec(Adr); + recN->SetName(SName); + recN->procInfo->flags = SFlags; + } + FillType(); + cbMethod->Enabled = false; + cbVmtCandidates->Enabled = false; + mType->Enabled = false; + cbEmbedded->Enabled = false; + lEndAdr->Enabled = false; + lStackSize->Enabled = false; + rgFunctionKind->Enabled = false; + rgCallKind->Enabled = false; + bApplyType->Enabled = false; + bCancelType->Enabled = false; + //Buttons + bEdit->Enabled = true; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + bOk->Enabled = false; + TypModified = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bApplyVarClick(TObject *Sender) +{ + int recofs, size; + String fname, ftype, name, type; + + try + { + recofs = StrToInt("$" + edtVarOfs->Text.Trim()); + } + catch (Exception &E) + { + ShowMessage("Invalid offset"); + edtVarOfs->SetFocus(); + return; + } + try + { + size = StrToInt("$" + edtVarSize->Text.Trim()); + } + catch (Exception &E) + { + ShowMessage("Invalid size"); + edtVarSize->SetFocus(); + return; + } + + //Insert by ZGL + PInfoRec recN = GetInfoRec(Adr); + PLOCALINFO locInfo = PLOCALINFO(recN->procInfo->locals->Items[lbVars->ItemIndex]); + //////////// + + recofs = locInfo->Ofs; + fname = edtVarName->Text.Trim(); + locInfo->Name = fname; //ZGL add + ftype = edtVarType->Text.Trim(); + locInfo->TypeDef = ftype; //ZGL add + recN->procInfo->SetLocalType(recofs, ftype); + /* + if (ftype != "" && GetTypeKind(ftype, &size) == ikRecord) + { + String recFileName = FMain_11011981->WrkDir + "\\types.idr"; + FILE* recFile = fopen(recFileName.c_str(), "rt"); + if (recFile) + { + while (1) + { + if (!fgets(StringBuf, 1024, recFile)) break; + String str = String(StringBuf); + if (str.Pos(ftype + "=") == 1) + { + while (1) + { + if (!fgets(StringBuf, 1024, recFile)) break; + str = String(StringBuf); + if (str.Pos("end;")) break; + int pos2 = str.Pos("//"); + if (pos2) + { + String ofs = str.SubString(pos2 + 2, str.Length()); + int pos1 = str.Pos(":"); + if (pos1) + { + name = str.SubString(1, pos1 - 1); + type = str.SubString(pos1 + 1, pos2 - pos1 - 1); + recN->procInfo->AddLocal(StrToInt("$" + ofs) + recofs, 1, fname + "." + name, type); + } + } + } + } + } + fclose(recFile); + } + while (1) + { + //KB + WORD* uses = KnowledgeBase.GetTypeUses(ftype.c_str()); + int idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, ftype.c_str()); + if (uses) delete[] uses; + + if (idx == -1) break; + + idx = KnowledgeBase.TypeOffsets[idx].NamId; + MTypeInfo tInfo; + if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS, &tInfo)) + { + if (tInfo.FieldsNum) + { + char* p = tInfo.Fields; + for (int k = 0; k < tInfo.FieldsNum; k++) + { + //Scope + p++; + int elofs = *((int*)p); p += 4; + p += 4;//case + //Name + int len = *((WORD*)p); p += 2; + name = String((char*)p, len); p += len + 1; + //Type + len = *((WORD*)p); p += 2; + type = TrimTypeName(String((char*)p, len)); p += len + 1; + recN->procInfo->AddLocal(recofs + elofs, 1, fname + "." + name, type); + } + break; + } + if (tInfo.Decl != "") + { + ftype = tInfo.Decl; + } + } + } + } + */ + FillVars(); + + pnlVars->Visible = false; + lbVars->Enabled = true; + lbArgs->Enabled = true; + + bEdit->Enabled = true; + bAdd->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + bOk->Enabled = true; + + VarModified = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bCancelVarClick(TObject *Sender) +{ + pnlVars->Visible = false; + lbVars->Enabled = true; + lbArgs->Enabled = true; + bOk->Enabled = false; + VarModified = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bRemoveSelectedClick(TObject *Sender) +{ + if (pc->ActivePage == tsVars) + { + PInfoRec recN = GetInfoRec(Adr); + for (int n = lbVars->Count - 1; n >= 0; n--) + { + if (lbVars->Selected[n]) + { + PLOCALINFO pLocInfo = (PLOCALINFO)recN->procInfo->locals->Items[n]; + recN->procInfo->DeleteLocal(n); + } + } + FillVars(); + bEdit->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = (lbVars->Count > 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bAddClick(TObject *Sender) +{ + String line, item; + if (pc->ActivePage == tsVars) + { + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FillVMTCandidates() +{ + if (!VmtCandidatesNum) + { + for (int m = 0; m < VmtList->Count; m++) + { + PVmtListRec recV = (PVmtListRec)VmtList->Items[m]; + cbVmtCandidates->Items->Add(recV->vmtName); + VmtCandidatesNum++; + } + cbMethod->Visible = (VmtCandidatesNum != 0); + cbVmtCandidates->Visible = (VmtCandidatesNum != 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FillType() +{ + BYTE callKind; + int argsBytes; + DWORD flags; + PInfoRec recN; + String line; + + mType->Clear(); + recN = GetInfoRec(Adr); + + switch (recN->kind) + { + case ikConstructor: + rgFunctionKind->ItemIndex = 0; + break; + case ikDestructor: + rgFunctionKind->ItemIndex = 1; + break; + case ikProc: + rgFunctionKind->ItemIndex = 2; + break; + case ikFunc: + rgFunctionKind->ItemIndex = 3; + break; + } + flags = recN->procInfo->flags; + callKind = flags & 7; + rgCallKind->ItemIndex = callKind; + cbEmbedded->Checked = (flags & PF_EMBED); + + line = recN->MakeMultilinePrototype(Adr, &argsBytes, (cbMethod->Checked) ? cbVmtCandidates->Text : String("")); + mType->Lines->Add(line); + //No VMT - nothing to choose + if (!VmtCandidatesNum) + { + cbMethod->Checked = false; + cbMethod->Visible = false; + cbVmtCandidates->Visible = false; + } + else + { + if (VmtCandidatesNum == 1) cbVmtCandidates->Text = cbVmtCandidates->Items->Strings[0]; + + if (recN->kind == ikConstructor || recN->kind == ikDestructor || (flags & PF_METHOD)) + { + cbMethod->Checked = true; + if (recN->HasName()) cbVmtCandidates->Text = ExtractClassName(recN->GetName()); + } + else + { + cbMethod->Checked = false; + } + + cbMethod->Visible = true; + cbVmtCandidates->Visible = true; + } + + recN->procInfo->flags &= ~PF_ARGSIZEL; + recN->procInfo->flags &= ~PF_ARGSIZEG; + if (argsBytes > recN->procInfo->retBytes) recN->procInfo->flags |= PF_ARGSIZEG; + if (argsBytes < recN->procInfo->retBytes) recN->procInfo->flags |= PF_ARGSIZEL; + + lRetBytes->Caption = String(recN->procInfo->retBytes); + lArgsBytes->Caption = String(argsBytes); +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FillArgs() +{ + BYTE callKind; + int n, cnt, wid, maxwid, offset; + TCanvas *canvas; + PInfoRec recN; + PARGINFO argInfo; + String line; + + lbArgs->Clear(); + recN = GetInfoRec(Adr); + if (recN->procInfo->args) + { + canvas = lbArgs->Canvas; maxwid = 0; + + cnt = recN->procInfo->args->Count; + callKind = recN->procInfo->flags & 7; + + if (callKind == 1 || callKind == 3)//cdecl, stdcall + { + for (n = 0; n < cnt; n++) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + line = Val2Str4(argInfo->Ndx) + " " + Val2Str2(argInfo->Size) + " "; + + if (argInfo->Name != "") + line += argInfo->Name; + else + line += "?"; + line += ":"; + if (argInfo->TypeDef != "") + line += argInfo->TypeDef; + else + line += "?"; + + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + lbArgs->Items->Add(line); + } + } + else if (callKind == 2)//pascal + { + for (n = cnt - 1; n >= 0; n--) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + line = Val2Str4(argInfo->Ndx) + " " + Val2Str2(argInfo->Size) + " "; + + if (argInfo->Name != "") + line += argInfo->Name; + else + line += "?"; + line += ":"; + if (argInfo->TypeDef != "") + line += argInfo->TypeDef; + else + line += "?"; + + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + lbArgs->Items->Add(line); + } + } + else//fastcall, safecall + { + offset = recN->procInfo->bpBase; + for (n = 0; n < cnt; n++) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + if (argInfo->Ndx > 2) + { + offset += argInfo->Size; + continue; + } + if (argInfo->Ndx == 0) + line = " eax "; + else if (argInfo->Ndx == 1) + line = " edx "; + else if (argInfo->Ndx == 2) + line = " ecx "; + + line += Val2Str2(argInfo->Size) + " "; + + if (argInfo->Tag == 0x22) line += "var "; + if (argInfo->Name != "") + line += argInfo->Name; + else + line += "?"; + line += ":"; + if (argInfo->TypeDef != "") + line += argInfo->TypeDef; + else + line += "?"; + + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + lbArgs->Items->Add(line); + } + for (n = 0; n < cnt; n++) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[n]; + if (argInfo->Ndx <= 2) continue; + + offset -= argInfo->Size; + line = Val2Str4(offset) + " " + Val2Str2(argInfo->Size) + " "; + + if (argInfo->Tag == 0x22) line += "var "; + if (argInfo->Name != "") + line += argInfo->Name; + else + line += "?"; + line += ":"; + if (argInfo->TypeDef != "") + line += argInfo->TypeDef; + else + line += "?"; + + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + lbArgs->Items->Add(line); + } + } + lbArgs->ScrollWidth = maxwid + 2; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FillVars() +{ + int n, wid, maxwid; + TCanvas *canvas; + PInfoRec recN; + PLOCALINFO locInfo; + String line; + + lbVars->Clear(); + rgLocBase->ItemIndex = -1; + recN = GetInfoRec(Adr); + if (recN->procInfo->locals) + { + rgLocBase->ItemIndex = (recN->procInfo->flags & PF_BPBASED); + + canvas = lbVars->Canvas; maxwid = 0; + for (n = 0; n < recN->procInfo->locals->Count; n++) + { + locInfo = (PLOCALINFO)recN->procInfo->locals->Items[n]; + line = Val2Str8(-locInfo->Ofs) + " " + Val2Str2(locInfo->Size) + " "; + if (locInfo->Name != "") + line += locInfo->Name; + else + line += "?"; + line += ":"; + if (locInfo->TypeDef != "") + line += locInfo->TypeDef; + else + line += "?"; + + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + lbVars->Items->Add(line); + } + lbVars->ScrollWidth = maxwid + 2; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FormClose(TObject *Sender, + TCloseAction &Action) +{ + if (!TypModified) + { + PInfoRec recN = GetInfoRec(Adr); + recN->SetName(SName); + recN->procInfo->flags = SFlags; + } + else + ProjectModified = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::cbMethodClick(TObject *Sender) +{ + PInfoRec recN = GetInfoRec(Adr); + if (cbMethod->Checked) + { + cbVmtCandidates->Enabled = true; + recN->procInfo->flags |= PF_METHOD; + FillType(); + cbVmtCandidates->Text = ((PARGINFO)recN->procInfo->args->Items[0])->TypeDef; + } + else + { + cbVmtCandidates->Enabled = false; + recN->procInfo->flags &= ~PF_METHOD; + FillType(); + cbVmtCandidates->Text = ""; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- +void __fastcall TFEditFunctionDlg_11011981::bRemoveAllClick( + TObject *Sender) +{ + PInfoRec recN = GetInfoRec(Adr); + if (recN->procInfo->locals) + { + recN->procInfo->DeleteLocals(); + FillVars(); + bEdit->Enabled = false; + bRemoveSelected->Enabled = false; + bRemoveAll->Enabled = false; + } +} +//--------------------------------------------------------------------------- diff --git a/Sources/Forms/EditFunctionDlg.dfm b/EditFunctionDlg.dfm similarity index 74% rename from Sources/Forms/EditFunctionDlg.dfm rename to EditFunctionDlg.dfm index d5fcc40..19bf395 100644 Binary files a/Sources/Forms/EditFunctionDlg.dfm and b/EditFunctionDlg.dfm differ diff --git a/EditFunctionDlg.h b/EditFunctionDlg.h new file mode 100644 index 0000000..45cf47c --- /dev/null +++ b/EditFunctionDlg.h @@ -0,0 +1,93 @@ +//---------------------------------------------------------------------------- +#ifndef EditFunctionDlgH +#define EditFunctionDlgH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Main.h" +//---------------------------------------------------------------------------- +class TFEditFunctionDlg_11011981 : public TForm +{ +__published: + TPanel *Panel1; + TButton *bEdit; + TButton *bAdd; + TButton *bRemoveSelected; + TPageControl *pc; + TTabSheet *tsArgs; + TListBox *lbArgs; + TTabSheet *tsVars; + TListBox *lbVars; + TPanel *pnlVars; + TRadioGroup *rgLocBase; + TLabeledEdit *edtVarOfs; + TLabeledEdit *edtVarSize; + TLabeledEdit *edtVarName; + TLabeledEdit *edtVarType; + TButton *bApplyVar; + TButton *bCancelVar; + TTabSheet *tsType; + TCheckBox *cbEmbedded; + TMemo *mType; + TRadioGroup *rgCallKind; + TButton *bApplyType; + TButton *bCancelType; + TRadioGroup *rgFunctionKind; + TButton *bOk; + TComboBox *cbVmtCandidates; + TCheckBox *cbMethod; + TLabel *Label1; + TLabel *lRetBytes; + TLabel *Label2; + TLabel *lArgsBytes; + TLabeledEdit *lEndAdr; + TLabeledEdit *lStackSize; + TButton *bRemoveAll; + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall bEditClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall pcChange(TObject *Sender); + void __fastcall lbVarsClick(TObject *Sender); + void __fastcall bCancelVarClick(TObject *Sender); + void __fastcall bApplyVarClick(TObject *Sender); + void __fastcall bRemoveSelectedClick(TObject *Sender); + void __fastcall bAddClick(TObject *Sender); + void __fastcall bApplyTypeClick(TObject *Sender); + void __fastcall bCancelTypeClick(TObject *Sender); + void __fastcall bOkClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall cbMethodClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall bRemoveAllClick(TObject *Sender); +private: + bool TypModified; + bool VarModified; + int ArgEdited; + int VmtCandidatesNum; + int StackSize; + DWORD SFlags; + String SName; + void __fastcall FillVMTCandidates(); + void __fastcall FillType(); + void __fastcall FillArgs(); + void __fastcall FillVars(); +public: + DWORD Adr; + DWORD EndAdr; + virtual __fastcall TFEditFunctionDlg_11011981(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFEditFunctionDlg_11011981 *FEditFunctionDlg_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/Exit.cpp b/Exit.cpp new file mode 100644 index 0000000..225c5d3 --- /dev/null +++ b/Exit.cpp @@ -0,0 +1,30 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Exit.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +TFExit_11011981 *FExit_11011981; +//--------------------------------------------------------------------- +__fastcall TFExit_11011981::TFExit_11011981(TComponent* AOwner) + : TForm(AOwner) +{ +} +//--------------------------------------------------------------------- +void __fastcall TFExit_11011981::OKBtnClick(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFExit_11011981::CancelBtnClick(TObject *Sender) +{ + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFExit_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Exit.dfm b/Exit.dfm new file mode 100644 index 0000000..3c9ef3a --- /dev/null +++ b/Exit.dfm @@ -0,0 +1,52 @@ +object FExit_11011981: TFExit_11011981 + Left = 482 + Top = 333 + BorderStyle = bsDialog + Caption = 'Save Project' + ClientHeight = 156 + ClientWidth = 385 + Color = clBtnFace + ParentFont = True + OldCreateOrder = True + Position = poScreenCenter + OnCreate = FormCreate + PixelsPerInch = 120 + TextHeight = 16 + object Bevel1: TBevel + Left = 10 + Top = 10 + Width = 365 + Height = 100 + Shape = bsFrame + end + object OKBtn: TButton + Left = 78 + Top = 123 + Width = 92 + Height = 31 + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 0 + OnClick = OKBtnClick + end + object CancelBtn: TButton + Left = 215 + Top = 123 + Width = 93 + Height = 31 + Cancel = True + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 1 + OnClick = CancelBtnClick + end + object cbDontSaveProject: TCheckBox + Left = 64 + Top = 49 + Width = 257 + Height = 21 + Caption = 'Don'#39't save Project' + TabOrder = 2 + end +end diff --git a/Exit.h b/Exit.h new file mode 100644 index 0000000..1cdb5d5 --- /dev/null +++ b/Exit.h @@ -0,0 +1,33 @@ +//---------------------------------------------------------------------------- +#ifndef ExitH +#define ExitH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TFExit_11011981 : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TBevel *Bevel1; + TCheckBox *cbDontSaveProject; + void __fastcall OKBtnClick(TObject *Sender); + void __fastcall CancelBtnClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: +public: + virtual __fastcall TFExit_11011981(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFExit_11011981 *FExit_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/Explorer.cpp b/Explorer.cpp new file mode 100644 index 0000000..582f0dd --- /dev/null +++ b/Explorer.cpp @@ -0,0 +1,313 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Explorer.h" +#include "Main.h" +#include "Misc.h" +#include +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "TntStdCtrls" +#pragma resource "*.dfm" + +extern MDisasm Disasm; +extern DWORD ImageBase; +extern DWORD ImageSize; +extern DWORD TotalSize; +extern DWORD CodeBase; +extern DWORD CodeSize; +extern BYTE *Image; +extern BYTE *Code; + +extern char StringBuf[MAXSTRBUFFER]; +extern PInfoRec *Infos; + +TFExplorer_11011981 *FExplorer_11011981; +//--------------------------------------------------------------------------- +__fastcall TFExplorer_11011981::TFExplorer_11011981(TComponent* Owner) + : TForm(Owner) +{ + WAlign = 0; + DefineAs = 0; + Adr = 0; + lbCode->Clear(); + lbData->Clear(); + lbString->Clear(); +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::ShowCode(DWORD fromAdr, int maxBytes) +{ + int pos; + DISINFO DisInfo; + char disLine[100]; + + lbCode->Clear(); + + pos = Adr2Pos(fromAdr); + if (pos == -1) return; + + Adr = fromAdr; + DWORD curAdr = Adr; + + for (int n = 0; n < maxBytes;) + { + int instrLen = Disasm.Disassemble(Code + pos, (__int64)curAdr, &DisInfo, disLine); + //if (!instrLen) break; + if (!instrLen) + { + instrLen = 1; + lbCode->Items->Add(Val2Str8(curAdr) + " ???"); + } + else + { + lbCode->Items->Add(Val2Str8(curAdr) + " " + disLine); + } + if (n + instrLen > maxBytes) break; + if (pos + instrLen >= CodeSize) break; + pos += instrLen; + curAdr += instrLen; + n += instrLen; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::ShowData(DWORD fromAdr, int maxBytes) +{ + BYTE b; + int n, k, m, pos; + float singleVal; + double doubleVal; + long double extendedVal; + double realVal; + Comp compVal; + String line1, line2; + + lbData->Clear(); + + pos = Adr2Pos(fromAdr); + if (pos == -1) return; + + Adr = fromAdr; + DWORD curAdr = Adr; + + switch (rgDataViewStyle->ItemIndex) + { + //Hex (default) + case 0: + for (n = 0, k = 0; n < maxBytes; n++) + { + if (pos > ImageSize) break; + if (!k) + { + line1 = Val2Str8(curAdr) + " "; + line2 = " "; + } + line1 += " " + Val2Str2(Image[pos]); + b = Image[pos]; + if (b < ' ') b = ' '; + line2 += String((char)b); + k++; + if (k == 16) + { + lbData->Items->Add(line1 + line2); + curAdr += 16; + k = 0; + } + pos++; + } + if (k > 0 && k < 16) + { + for (m = k; m < 16; m++) line1 += " "; + lbData->Items->Add(line1 + line2); + } + break; + //Single = float + case 1: + singleVal = 0; memmove((void*)&singleVal, Image + pos, 4); + line1 = Val2Str8(curAdr) + " " + FloatToStr(singleVal); + lbData->Items->Add(line1); + break; + //Double = doulbe + case 2: + doubleVal = 0; memmove((void*)&doubleVal, Image + pos, 8); + line1 = Val2Str8(curAdr) + " " + FloatToStr(doubleVal); + lbData->Items->Add(line1); + break; + //Extended = long double + case 3: + try + { + extendedVal = 0; memmove((void*)&extendedVal, Image + pos, 10); + line1 = Val2Str8(curAdr) + " " + FloatToStr(extendedVal); + } + catch (Exception &E) + { + line1 = "Impossible!"; + } + lbData->Items->Add(line1); + break; + //Real = double + case 4: + realVal = 0; memmove((void*)&realVal, Image + pos, 4); + line1 = Val2Str8(curAdr) + " " + FloatToStr(realVal); + lbData->Items->Add(line1); + break; + //Comp = Comp + case 5: + compVal = 0; memmove((void*)&compVal, Image + pos, 8); + line1 = Val2Str8(curAdr) + " " + FloatToStr(compVal); + lbData->Items->Add(line1); + break; + } + lbData->Update(); +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::ShowString(DWORD fromAdr, int maxBytes) +{ + int len, size, pos; + DWORD adr, resid; + char *tmpBuf; + HINSTANCE hInst; + String str; + WideString wStr; + char buf[1024]; + + lbString->Clear(); + + pos = Adr2Pos(fromAdr); + if (pos == -1) return; + + switch (rgStringViewStyle->ItemIndex) + { + case 0: //PAnsiChar + len = strlen((char*)(Image + pos)); + if (len < 0) len = 0; + if (len > maxBytes) len = maxBytes; + str = TransformString(Image + pos, len); + break; + case 1: //PWideChar + len = wcslen((wchar_t*)(Image + pos)); + if (len < 0) len = 0; + if (len > maxBytes) len = maxBytes; + wStr = WideString((wchar_t*)(Image + pos)); + size = WideCharToMultiByte(CP_ACP, 0, wStr, len, 0, 0, 0, 0); + if (size) + { + tmpBuf = new char[size + 1]; + WideCharToMultiByte(CP_ACP, 0, wStr, len, (LPSTR)tmpBuf, size, 0, 0); + str = TransformString(tmpBuf, size); + delete[] tmpBuf; + } + break; + case 2: //ShortString + len = *(Image + pos); + if (len < 0) len = 0; + if (len > maxBytes) len = maxBytes; + str = TransformString(Image + pos + 1, len); + break; + case 3: //AnsiString + len = *((int*)(Image + pos)); + if (len < 0) len = 0; + if (len > maxBytes) len = maxBytes; + str = TransformString(Image + pos + 4, len); + break; + case 4: //WideString + len = *((int*)(Image + pos + WAlign)); + if (len < 0) len = 0; + if (len > maxBytes) len = maxBytes; + wStr = WideString((wchar_t*)(Image + pos + WAlign + 4)); + size = WideCharToMultiByte(CP_ACP, 0, wStr, len, 0, 0, 0, 0); + if (size) + { + tmpBuf = new char[size + 1]; + WideCharToMultiByte(CP_ACP, 0, wStr, len, (LPSTR)tmpBuf, size, 0, 0); + str = TransformString(tmpBuf, size); + delete[] tmpBuf; + } + break; + } + + lbString->Lines->Add(str); +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::ShowArray(DWORD fromAdr) +{ +/* + lbArray->Clear(); + + int pos = Adr2Pos(fromAdr); + DWORD curAdr = fromAdr; + + for (int n = 0; n < 32; n++) + { + if (pos > TotalSize) break; + DWORD Adr = *((DWORD*)(Image + pos)); + if (!IsValidImageAdr(Adr)) break; + char* p = Image + Adr2Pos(Adr); + String s = String(p); + lbArray->Items->Add(s); + pos += 4; + } +*/ +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::btnDefCodeClick(TObject *Sender) +{ + DefineAs = DEFINE_AS_CODE; + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::btnUndefCodeClick(TObject *Sender) +{ + DefineAs = UNDEFINE; + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::btnDefStringClick(TObject *Sender) +{ + DefineAs = DEFINE_AS_STRING; + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::rgStringViewStyleClick(TObject *Sender) +{ + ShowString(Adr, 1024); +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::miCopy2ClipboardClick(TObject *Sender) +{ + TStrings* items; + + if (pc1->ActivePage == tsCode) + items = lbCode->Items; + else if (pc1->ActivePage == tsData) + items = lbData->Items; + else if (pc1->ActivePage == tsString) + items = lbString->Lines; + else if (pc1->ActivePage == tsText) + items = lbText->Items; + + Copy2Clipboard(items, 0, false); +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) +{ + if (Key == VK_ESCAPE) ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::FormShow(TObject *Sender) +{ + DefineAs = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::rgDataViewStyleClick(TObject *Sender) +{ + ShowData(Adr, 1024); +} +//--------------------------------------------------------------------------- +void __fastcall TFExplorer_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/Explorer.dfm b/Explorer.dfm similarity index 61% rename from Sources/Forms/Explorer.dfm rename to Explorer.dfm index 4723a20..22ed3c6 100644 Binary files a/Sources/Forms/Explorer.dfm and b/Explorer.dfm differ diff --git a/Explorer.h b/Explorer.h new file mode 100644 index 0000000..b7575ee --- /dev/null +++ b/Explorer.h @@ -0,0 +1,66 @@ +//--------------------------------------------------------------------------- + +#ifndef ExplorerH +#define ExplorerH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include "TntStdCtrls.hpp" +//--------------------------------------------------------------------------- +#define DEFINE_AS_CODE 1 +#define DEFINE_AS_STRING 2 +#define UNDEFINE 3 + +class TFExplorer_11011981 : public TForm +{ +__published: // IDE-managed Components + TPageControl *pc1; + TTabSheet *tsCode; + TTabSheet *tsData; + TListBox *lbCode; + TListBox *lbData; + TTabSheet *tsString; + TRadioGroup *rgStringViewStyle; + TTabSheet *tsText; + TListBox *lbText; + TPopupMenu *pm1; + TMenuItem *miCopy2Clipboard; + TPanel *Panel2; + TRadioGroup *rgDataViewStyle; + TMemo *lbString; + TPanel *Panel3; + TButton *btnDefCode; + TButton *btnUndefCode; + TPanel *Panel1; + TButton *btnDefString; + TButton *btnUndefString; + void __fastcall btnDefCodeClick(TObject *Sender); + void __fastcall btnUndefCodeClick(TObject *Sender); + void __fastcall rgStringViewStyleClick(TObject *Sender); + void __fastcall miCopy2ClipboardClick(TObject *Sender); + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall FormShow(TObject *Sender); + void __fastcall rgDataViewStyleClick(TObject *Sender); + void __fastcall btnDefStringClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: // User declarations + DWORD Adr; //Àäðåñ, ñ êîòîðîãî ïîêàçûâàåòñÿ èíôîðìàöèÿ +public: // User declarations + __fastcall TFExplorer_11011981(TComponent* Owner); + void __fastcall ShowCode(DWORD fromAdr, int maxBytes); + void __fastcall ShowData(DWORD fromAdr, int maxBytes); + void __fastcall ShowString(DWORD fromAdr, int maxbytes); + void __fastcall ShowArray(DWORD fromAdr); + int DefineAs; //1- Define as Code, 2 - Undefine + int WAlign; //Alignment for WideString visualization +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFExplorer_11011981 *FExplorer_11011981; +//--------------------------------------------------------------------------- +#endif diff --git a/FindDlg.cpp b/FindDlg.cpp new file mode 100644 index 0000000..b25063a --- /dev/null +++ b/FindDlg.cpp @@ -0,0 +1,32 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "FindDlg.h" +#include "Misc.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +TFindDlg_11011981 *FindDlg_11011981; +//--------------------------------------------------------------------- +__fastcall TFindDlg_11011981::TFindDlg_11011981(TComponent* AOwner) + : TForm(AOwner) +{ +} +//--------------------------------------------------------------------- +void __fastcall TFindDlg_11011981::FormShow(TObject *Sender) +{ + if (cbText->Items->Count) cbText->Text = cbText->Items->Strings[0]; + ActiveControl = cbText; +} +//--------------------------------------------------------------------------- +void __fastcall TFindDlg_11011981::cbTextEnter(TObject *Sender) +{ + cbText->SelectAll(); +} +//--------------------------------------------------------------------------- +void __fastcall TFindDlg_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/FindDlg.dfm b/FindDlg.dfm similarity index 87% rename from Sources/Forms/FindDlg.dfm rename to FindDlg.dfm index 0d77df8..6a976cb 100644 --- a/Sources/Forms/FindDlg.dfm +++ b/FindDlg.dfm @@ -12,7 +12,7 @@ object FindDlg_11011981: TFindDlg_11011981 OnCreate = FormCreate OnShow = FormShow PixelsPerInch = 120 - TextHeight = 13 + TextHeight = 16 object Bevel1: TBevel Left = 10 Top = 10 @@ -23,8 +23,8 @@ object FindDlg_11011981: TFindDlg_11011981 object Label1: TLabel Left = 30 Top = 30 - Width = 60 - Height = 13 + Width = 67 + Height = 16 Caption = 'Text to find:' end object OKBtn: TButton @@ -53,7 +53,8 @@ object FindDlg_11011981: TFindDlg_11011981 Left = 108 Top = 25 Width = 307 - Height = 21 + Height = 24 + ItemHeight = 16 TabOrder = 2 OnEnter = cbTextEnter end diff --git a/FindDlg.h b/FindDlg.h new file mode 100644 index 0000000..d23eb85 --- /dev/null +++ b/FindDlg.h @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------------- +#ifndef FindDlgH +#define FindDlgH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TFindDlg_11011981 : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TBevel *Bevel1; + TComboBox *cbText; + TLabel *Label1; + void __fastcall FormShow(TObject *Sender); + void __fastcall cbTextEnter(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: +public: + virtual __fastcall TFindDlg_11011981(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFindDlg_11011981 *FindDlg_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/Hex2Double.cpp b/Hex2Double.cpp new file mode 100644 index 0000000..9abe0a0 --- /dev/null +++ b/Hex2Double.cpp @@ -0,0 +1,194 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Hex2Double.h" +#include +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +TFHex2DoubleDlg_11011981 *FHex2DoubleDlg_11011981; +//--------------------------------------------------------------------- +__fastcall TFHex2DoubleDlg_11011981::TFHex2DoubleDlg_11011981(TComponent* AOwner) + : TForm(AOwner) +{ +} +//--------------------------------------------------------------------- +void __fastcall TFHex2DoubleDlg_11011981::FormShow(TObject *Sender) +{ + rgDataViewStyle->ItemIndex = 0; + PrevIdx = 0; + edtValue->Text = ""; + if (edtValue->CanFocus()) ActiveControl = edtValue; +} +//--------------------------------------------------------------------------- +void __fastcall TFHex2DoubleDlg_11011981::edtValueEnter(TObject *Sender) +{ + edtValue->SelectAll(); +} +//--------------------------------------------------------------------------- +void __fastcall TFHex2DoubleDlg_11011981::Str2Binary(String AStr) +{ + BYTE c; + int val, pos, n; + char *src; + + src = AStr.c_str(); + memset(BinData, 0, 16); n = 0; + + while (1) + { + c = *src; + if (!c) break; + if (c != ' ') + { + sscanf(src, "%X", &val); + BinData[n] = val; n++; + while (1) + { + c = *src; + if (!c || c == ' ') break; + src++; + } + if (!c) break; + } + src++; + } +} +//--------------------------------------------------------------------------- +String __fastcall TFHex2DoubleDlg_11011981::Binary2Str(int BytesNum) +{ + String result = ""; + for (int n = 0; n < BytesNum; n++) + { + if (n) result += " "; + result += Val2Str2(BinData[n]); + } + return result; +} +//--------------------------------------------------------------------------- +void __fastcall TFHex2DoubleDlg_11011981::rgDataViewStyleClick(TObject *Sender) +{ + int n; + float singleVal; + double doubleVal; + long double extendedVal; + double realVal; + Comp compVal; + String result; + + if (edtValue->Text == "") + { + PrevIdx = rgDataViewStyle->ItemIndex; + return; + } + if (rgDataViewStyle->ItemIndex == PrevIdx) return; + + result = edtValue->Text; + try + { + if (rgDataViewStyle->ItemIndex == 0)//Hex + { + memset((void*)BinData, 0, 16); + if (PrevIdx == FT_SINGLE) + { + singleVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &singleVal, 4); + result = Binary2Str(4); + } + else if (PrevIdx == FT_DOUBLE) + { + doubleVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &doubleVal, 8); + result = Binary2Str(8); + } + else if (PrevIdx == FT_EXTENDED) + { + extendedVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &extendedVal, 10); + result = Binary2Str(10); + } + else if (PrevIdx == FT_REAL) + { + realVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &realVal, 4); + result = Binary2Str(4); + } + else if (PrevIdx == FT_COMP) + { + compVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &compVal, 8); + result = Binary2Str(8); + } + } + else + { + if (PrevIdx == 0) + { + Str2Binary(edtValue->Text); + } + else if (PrevIdx == FT_SINGLE) + { + singleVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &singleVal, 4); + } + else if (PrevIdx == FT_DOUBLE) + { + doubleVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &doubleVal, 8); + } + else if (PrevIdx == FT_EXTENDED) + { + extendedVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &extendedVal, 10); + } + else if (PrevIdx == FT_REAL) + { + realVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &realVal, 4); + } + else if (PrevIdx == FT_COMP) + { + compVal = StrToFloat(edtValue->Text); + memmove((void*)BinData, &compVal, 8); + } + if (rgDataViewStyle->ItemIndex == FT_SINGLE) + { + singleVal = 0; memmove((void*)&singleVal, BinData, 4); + result = FloatToStr(singleVal); + } + else if (rgDataViewStyle->ItemIndex == FT_DOUBLE) + { + doubleVal = 0; memmove((void*)&doubleVal, BinData, 8); + result = FloatToStr(doubleVal); + } + else if (rgDataViewStyle->ItemIndex == FT_EXTENDED) + { + extendedVal = 0; memmove((void*)&extendedVal, BinData, 10); + result = FloatToStr(extendedVal); + } + else if (rgDataViewStyle->ItemIndex == FT_REAL) + { + realVal = 0; memmove((void*)&realVal, BinData, 4); + result = FloatToStr(realVal); + } + else if (rgDataViewStyle->ItemIndex == FT_COMP) + { + compVal = 0; memmove((void*)&compVal, BinData, 8); + result = FloatToStr(compVal); + } + } + } + catch (Exception &E) + { + result = "Impossible!"; + } + PrevIdx = rgDataViewStyle->ItemIndex; + edtValue->Text = result; +} +//--------------------------------------------------------------------------- +void __fastcall TFHex2DoubleDlg_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/Hex2Double.dfm b/Hex2Double.dfm similarity index 89% rename from Sources/Forms/Hex2Double.dfm rename to Hex2Double.dfm index dc0c62a..7743f7a 100644 --- a/Sources/Forms/Hex2Double.dfm +++ b/Hex2Double.dfm @@ -12,7 +12,7 @@ object FHex2DoubleDlg_11011981: TFHex2DoubleDlg_11011981 OnCreate = FormCreate OnShow = FormShow PixelsPerInch = 120 - TextHeight = 13 + TextHeight = 16 object rgDataViewStyle: TRadioGroup Left = 0 Top = 0 @@ -36,8 +36,8 @@ object FHex2DoubleDlg_11011981: TFHex2DoubleDlg_11011981 Top = 56 Width = 697 Height = 28 - EditLabel.Width = 36 - EditLabel.Height = 16 + EditLabel.Width = 60 + EditLabel.Height = 20 EditLabel.Caption = 'Value:' EditLabel.Font.Charset = RUSSIAN_CHARSET EditLabel.Font.Color = clWindowText @@ -51,6 +51,7 @@ object FHex2DoubleDlg_11011981: TFHex2DoubleDlg_11011981 Font.Name = 'Fixedsys' Font.Style = [] LabelPosition = lpLeft + LabelSpacing = 3 ParentFont = False TabOrder = 1 OnEnter = edtValueEnter diff --git a/Hex2Double.h b/Hex2Double.h new file mode 100644 index 0000000..27146dc --- /dev/null +++ b/Hex2Double.h @@ -0,0 +1,37 @@ +//---------------------------------------------------------------------------- +#ifndef Hex2DoubleH +#define Hex2DoubleH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Misc.h" +//---------------------------------------------------------------------------- +class TFHex2DoubleDlg_11011981 : public TForm +{ +__published: + TRadioGroup *rgDataViewStyle; + TLabeledEdit *edtValue; + void __fastcall FormShow(TObject *Sender); + void __fastcall edtValueEnter(TObject *Sender); + void __fastcall rgDataViewStyleClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: + int PrevIdx; + BYTE BinData[16]; + void __fastcall Str2Binary(String AStr); + String __fastcall Binary2Str(int BytesNum); +public: + virtual __fastcall TFHex2DoubleDlg_11011981(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFHex2DoubleDlg_11011981 *FHex2DoubleDlg_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/IDCGen.cpp b/IDCGen.cpp new file mode 100644 index 0000000..c5d22a5 --- /dev/null +++ b/IDCGen.cpp @@ -0,0 +1,1343 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Misc.h" +#include "IDCGen.h" +//--------------------------------------------------------------------------- +extern MDisasm Disasm; +extern DWORD CodeBase; +extern BYTE *Code; +extern int DelphiVersion; +extern DWORD *Flags; +extern PInfoRec *Infos; +extern bool SplitIDC; +//--------------------------------------------------------------------------- +__fastcall TIDCGen::TIDCGen(FILE* FIdc, int splitSize) +{ + idcF = FIdc; + unitName = ""; + itemName = ""; + names = new TStringList; + repeated = new TList; + SplitSize = splitSize; + CurrentPartNo = 1; + CurrentBytes = 0; +} +//--------------------------------------------------------------------------- +__fastcall TIDCGen::~TIDCGen() +{ + delete names; + delete repeated; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::NewIDCPart(FILE* FIdc) +{ + idcF = FIdc; + CurrentBytes = 0; + CurrentPartNo++; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::DeleteName(int pos) +{ + DWORD adr = Pos2Adr(pos); + + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"\", 0);\n", adr); +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeByte(int pos) +{ + CurrentBytes += fprintf(idcF, "MakeByte(0x%lX);\n", Pos2Adr(pos)); + return pos + 1; +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeWord(int pos) +{ + CurrentBytes += fprintf(idcF, "MakeWord(0x%lX);\n", Pos2Adr(pos)); + return pos + 2; +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeDword(int pos) +{ + CurrentBytes += fprintf(idcF, "MakeDword(0x%lX);\n", Pos2Adr(pos)); + return pos + 4; +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeQword(int pos) +{ + CurrentBytes += fprintf(idcF, "MakeQword(0x%lX);\n", Pos2Adr(pos)); + return pos + 8; +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeArray(int pos, int num) +{ + CurrentBytes += fprintf(idcF, "MakeByte(0x%lX);\n", Pos2Adr(pos)); + CurrentBytes += fprintf(idcF, "MakeArray(0x%lX, %d);\n", Pos2Adr(pos), num); + return pos + num; +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeShortString(int pos) +{ + BYTE len = Code[pos]; + //Empty String + if (!len) return pos + 1; + + if (!IsValidName(len, pos + 1)) return pos; + + CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_PASCAL);\n"); + CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, 0x%lX);\n", Pos2Adr(pos), Pos2Adr(pos) + len + 1); + return pos + len + 1; +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeCString(int pos) +{ + int len = strlen(Code + pos); + CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_TERMCHR);\n"); + CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, 0x%lX);\n", Pos2Adr(pos), Pos2Adr(pos) + len + 1); + return pos + len + 1; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::MakeLString(int pos) +{ + CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_TERMCHR);\n"); + CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, -1);\n", Pos2Adr(pos)); + //Length + MakeDword(pos - 4); + //RefCount + MakeDword(pos - 8); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::MakeWString(int pos) +{ + CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);\n"); + CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, -1);\n", Pos2Adr(pos)); + //Length + MakeDword(pos - 4); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::MakeUString(int pos) +{ + CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);\n"); + CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, -1);\n", Pos2Adr(pos)); + //Length + MakeDword(pos - 4); + //RefCount + MakeDword(pos - 8); + //Word + MakeWord(pos - 10); + //CodePage + MakeWord(pos - 12); +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::MakeCode(int pos) +{ + DISINFO DisInfo; + + CurrentBytes += fprintf(idcF, "MakeCode(0x%lX);\n", Pos2Adr(pos)); + int instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), 0, 0); + if (!instrLen) instrLen = 1; + return instrLen; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::MakeFunction(DWORD adr) +{ + if (adr) + { + CurrentBytes += fprintf(idcF, "MakeFunction(0x%lX, -1);\n", adr); + MakeCode(Adr2Pos(adr)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::MakeComment(int pos, String text) +{ + CurrentBytes += fprintf(idcF, "MakeComm(0x%lX, \"%s\");\n", Pos2Adr(pos), TransformString(text.c_str(), text.Length()).c_str()); +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::OutputAttrData(int pos) +{ + WORD dw = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + return pos; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputHeaderFull() +{ + CurrentBytes += fprintf(idcF, "#include \n"); + CurrentBytes += fprintf(idcF, "static clear(from){\n"); + CurrentBytes += fprintf(idcF, "auto ea;\n"); + CurrentBytes += fprintf(idcF, "ea = from;\n"); + CurrentBytes += fprintf(idcF, "while (1){\n"); + CurrentBytes += fprintf(idcF, "ea = NextFunction(ea);\n"); + CurrentBytes += fprintf(idcF, "if (ea == -1) break;\n"); + CurrentBytes += fprintf(idcF, "DelFunction(ea);\n"); + CurrentBytes += fprintf(idcF, "MakeNameEx(ea, \"\", 0);}\n"); + CurrentBytes += fprintf(idcF, "ea = from;\n"); + CurrentBytes += fprintf(idcF, "while (1){\n"); + CurrentBytes += fprintf(idcF, "ea = FindExplored(ea, SEARCH_DOWN | SEARCH_NEXT);\n"); + CurrentBytes += fprintf(idcF, "if (ea == -1) break;\n"); + CurrentBytes += fprintf(idcF, "MakeUnkn(ea, 1);}\n"); + CurrentBytes += fprintf(idcF, "}\n"); + CurrentBytes += fprintf(idcF, "static main(){\n"); + CurrentBytes += fprintf(idcF, "clear(0x%lX);\n", CodeBase); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputHeaderShort() +{ + CurrentBytes += fprintf(idcF, "#include \n"); + CurrentBytes += fprintf(idcF, "static main(){\n"); +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::OutputRTTIHeader(BYTE kind, int pos) +{ + int fromPos = pos; + + BYTE len = *(Code + pos + 5); + itemName = String((char*)(Code + pos + 6), len); + DWORD adr = Pos2Adr(pos); + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"RTTI_%lX_%s_%s\", 0);\n", adr, adr, TypeKind2Name(kind).c_str(), itemName.c_str()); + //Selfptr + pos = MakeDword(pos); + //Kind + //Delete name (often presents) + DeleteName(pos); + pos = MakeByte(pos); + //Name + pos = MakeShortString(pos); + return pos - fromPos; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIInteger(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //ordType + pos = MakeByte(pos); + //minValue + pos = MakeDword(pos); + //maxValue + pos = MakeDword(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIChar(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //ordType + pos = MakeByte(pos); + //minValue + pos = MakeDword(pos); + //maxValue + pos = MakeDword(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIEnumeration(BYTE kind, int pos, DWORD adr) +{ + pos += OutputRTTIHeader(kind, pos); + //ordType + pos = MakeByte(pos); + //minValue + DWORD minValue = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + //maxValue + DWORD maxValue = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + //baseTypeAdr + DWORD baseTypeAdr = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + + if (baseTypeAdr == adr) + { + if (SameText(itemName, "ByteBool") || + SameText(itemName, "WordBool") || + SameText(itemName, "LongBool")) + { + minValue = 0; + maxValue = 1; + } + + for (int n = minValue; n <= maxValue; n++) + { + pos = MakeShortString(pos); + } + } + //UnitName + //pos = MakeShortString(pos); + //if (DelphiVersion == 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIFloat(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //FloatType + pos = MakeByte(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIString(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //MaxLength + pos = MakeByte(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTISet(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //OrdType + pos = MakeByte(pos); + //CompType + pos = MakeDword(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIClass(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //classVMT + pos = MakeDword(pos); + //ParentInfo + pos = MakeDword(pos); + //PropCount + pos = MakeWord(pos); + //UnitName + pos = MakeShortString(pos); + //PropData + WORD Count = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + for (int n = 0; n < Count; n++) + { + //TPropInfo + for (int m = 0; m < 6; m++) + { + pos = MakeDword(pos); + } + pos = MakeWord(pos); + pos = MakeShortString(pos); + } + if (DelphiVersion >= 2010) + { + //PropDataEx + Count = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + for (int n = 0; n < Count; n++) + { + //Flags + pos = MakeByte(pos); + //Info + DWORD typeInfo = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + for (int m = 0; m < 6; m++) + { + MakeDword(Adr2Pos(typeInfo)); + typeInfo += 4; + } + MakeWord(Adr2Pos(typeInfo)); typeInfo += 2; + MakeShortString(Adr2Pos(typeInfo)); + //AttrData + pos = OutputAttrData(pos); + } + //AttrData + OutputAttrData(pos); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIMethod(BYTE kind, int pos) +{ + int _pos = pos, pos1; + + pos += OutputRTTIHeader(kind, pos); + //MethodKind + BYTE methodKind = Code[pos]; + pos = MakeByte(pos); + //ParamCnt + BYTE paramCnt = Code[pos]; + pos = MakeByte(pos); + + for (int n = 0; n < paramCnt; n++) + { + //Flags + pos = MakeByte(pos); + //ParamName + pos = MakeShortString(pos); + //TypeName + pos = MakeShortString(pos); + } + + if (methodKind) + { + //ResultType + pos = MakeShortString(pos); + if (DelphiVersion > 6) + { + //ResultTypeRef + pos = MakeDword(pos); + } + } + + if (DelphiVersion > 6) + { + //CC (TCallConv) + pos = MakeByte(pos); + //ParamTypeRefs + for (int n = 0; n < paramCnt; n++) + { + pos = MakeDword(pos); + } + if (DelphiVersion >= 2010) + { + DWORD procSig = *((DWORD*)(Code + pos)); + //MethSig + pos = MakeDword(pos); + //AttrData + OutputAttrData(pos); + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + pos1 = Adr2Pos(procSig); + else + pos1 = _pos + procSig; + //Flags + BYTE flags = Code[pos1]; + pos1 = MakeByte(pos1); + if (flags != 0xFF) + { + //CC + pos1 = MakeByte(pos1); + //ResultType + pos1 = MakeDword(pos1); + //ParamCount + paramCnt = Code[pos1]; + pos1 = MakeByte(pos1); + for (int n = 0; n < paramCnt; n++) + { + //Flags + pos1 = MakeByte(pos1); + //ParamType + pos1 = MakeDword(pos1); + //Name + pos1 = MakeShortString(pos1); + //AttrData + pos1 = OutputAttrData(pos1); + } + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIWChar(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //ordType + pos = MakeByte(pos); + //minValue + pos = MakeDword(pos); + //maxValue + pos = MakeDword(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTILString(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + if (DelphiVersion >= 2009) + { + //CodePage + pos = MakeWord(pos); + } + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIWString(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIVariant(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIArray(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //Size + pos = MakeDword(pos); + //ElCount + pos = MakeDword(pos); + //ElType + pos = MakeDword(pos); + + if (DelphiVersion >= 2010) + { + //DimCount + BYTE dimCnt = Code[pos]; + pos = MakeByte(pos); + for (int n = 0; n < dimCnt; n++) + { + //Dims + pos = MakeDword(pos); + } + //AttrData + OutputAttrData(pos); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIRecord(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //Size + pos = MakeDword(pos); + //ManagedFldCount + int n, m, elNum = *((int*)(Code + pos)); + pos = MakeDword(pos); + for (n = 0; n < elNum; n++) + { + //TypeRef + pos = MakeDword(pos); + //FldOffset + pos = MakeDword(pos); + } + + if (DelphiVersion >= 2010) + { + //NumOps + BYTE numOps = Code[pos]; + pos = MakeByte(pos); + for (n = 0; n < numOps; n++) //RecOps + { + pos = MakeDword(pos); + } + //RecFldCnt + elNum = *((int*)(Code + pos)); + pos = MakeDword(pos); + + for (n = 0; n < elNum; n++) + { + //TypeRef + pos = MakeDword(pos); + //FldOffset + pos = MakeDword(pos); + //Flags + pos = MakeByte(pos); + //Name + pos = MakeShortString(pos); + //AttrData + pos = OutputAttrData(pos); + } + //AttrData + pos = OutputAttrData(pos); + if (DelphiVersion >= 2012) + { + WORD methCnt = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + for (n = 0; n < methCnt; n++) + { + //Flags + pos = MakeByte(pos); + //Code + pos = MakeDword(pos); + //Name + pos = MakeShortString(pos); + //ProcedureSignature + //Flags + BYTE flags = Code[pos]; + pos = MakeByte(pos); + if (flags != 0xFF) + { + //CC + pos = MakeByte(pos); + //ResultType + pos = MakeDword(pos); + BYTE paramCnt = Code[pos]; + pos = MakeByte(pos); + //Params + for (m = 0; m < paramCnt; m++) + { + //Flags + pos = MakeByte(pos); + //ParamType + pos = MakeDword(pos); + //Name + pos = MakeShortString(pos); + //AttrData + pos = OutputAttrData(pos); + } + } + //AttrData + pos = OutputAttrData(pos); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIInterface(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //IntfParent + pos = MakeDword(pos); + //IntfFlags + pos = MakeByte(pos); + //GUID + pos = MakeArray(pos, 16); + //UnitName + pos = MakeShortString(pos); + //PropCount + WORD Count = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + + if (DelphiVersion >= 6) + { + //RttiCount + WORD dw = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + if (dw != 0xFFFF) + { + if (DelphiVersion >= 2010) + { + for (int n = 0; n < Count; n++) + { + //Name + pos = MakeShortString(pos); + //Kind + BYTE methodKind = Code[pos]; + pos = MakeByte(pos); + //CallConv + pos = MakeByte(pos); + //ParamCount + BYTE paramCnt = Code[pos]; + pos = MakeByte(pos); + + for (int m = 0; m < paramCnt; m++) + { + //Flags + pos = MakeByte(pos); + //ParamName + pos = MakeShortString(pos); + //TypeName + pos = MakeShortString(pos); + //ParamType + pos = MakeDword(pos); + } + if (methodKind) + { + //ResultTypeName + BYTE len = Code[pos]; + pos = MakeShortString(pos); + if (len) + { + //ResultType + pos = MakeDword(pos); + } + } + } + } + else + { + for (int n = 0; n < Count; n++) + { + //PropType + pos = MakeDword(pos); + //GetProc + pos = MakeDword(pos); + //SetProc + pos = MakeDword(pos); + //StoredProc + pos = MakeDword(pos); + //Index + pos = MakeDword(pos); + //Default + pos = MakeDword(pos); + //NameIndex + pos = MakeWord(pos); + //Name + pos = MakeShortString(pos); + } + } + } + if (DelphiVersion >= 2010) + { + //AttrData + OutputAttrData(pos); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIInt64(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //MinVal + pos = MakeQword(pos); + //MaxVal + pos = MakeQword(pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIDynArray(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //elSize + pos = MakeDword(pos); + //elType + pos = MakeDword(pos); + //varType + pos = MakeDword(pos); + + if (DelphiVersion >= 6) + { + //elType2 + pos = MakeDword(pos); + //UnitName + pos = MakeShortString(pos); + } + if (DelphiVersion >= 2010) + { + //DynArrElType + pos = MakeDword(pos); + //AttrData + OutputAttrData(pos); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIUString(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + if (DelphiVersion >= 2010) OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIClassRef(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //InstanceType + pos = MakeDword(pos); + //AttrData + OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIPointer(BYTE kind, int pos) +{ + pos += OutputRTTIHeader(kind, pos); + //RefType + pos = MakeDword(pos); + //AttrData + OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputRTTIProcedure(BYTE kind, int pos) +{ + int _pos = pos; + + pos += OutputRTTIHeader(kind, pos); + //MethSig + DWORD procSig = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + //AttrData + pos = OutputAttrData(pos); + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + pos = Adr2Pos(procSig); + else + pos = _pos + procSig; + //Flags + BYTE flags = Code[pos]; + pos = MakeByte(pos); + if (flags != 0xFF) + { + //CallConv + pos = MakeByte(pos); + //ResultType + pos = MakeDword(pos); + //ParamCnt + BYTE paramCnt = Code[pos]; + pos = MakeByte(pos); + for (int n = 0; n < paramCnt; n++) + { + //Flags + pos = MakeByte(pos); + //ParamType + pos = MakeDword(pos); + //Name + pos = MakeShortString(pos); + //AttrData + pos = OutputAttrData(pos); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputVMT(int pos, PInfoRec recN) +{ + itemName = recN->GetName(); + pos += OutputVMTHeader(pos, itemName); + if (DelphiVersion >= 3) + { + //VmtIntfTable + OutputIntfTable(pos); pos += 4; + //VmtAutoTable + OutputAutoTable(pos); pos += 4; + } + //VmtInitTable + OutputInitTable(pos); pos += 4; + //VmtTypeInfo + pos = MakeDword(pos); + //VmtFieldTable + OutputFieldTable(pos); pos += 4; + //VmtMethodTable + OutputMethodTable(pos); pos += 4; + //VmtDynamicTable + OutputDynamicTable(pos); pos += 4; + //VmtClassName + DWORD nameAdr = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + MakeShortString(Adr2Pos(nameAdr)); + //VmtInstanceSize + pos = MakeDword(pos); + //VmtParent + pos = MakeDword(pos); + if (DelphiVersion >= 2009) + { + //VmtEquals + pos = MakeDword(pos); + //VmtGetHashCode + pos = MakeDword(pos); + //VmtToString + pos = MakeDword(pos); + } + if (DelphiVersion >= 3) + { + //VmtSafeCallException + pos = MakeDword(pos); + } + if (DelphiVersion >= 4) + { + //VmtAfterConstruction + pos = MakeDword(pos); + //VmtBeforeDestruction + pos = MakeDword(pos); + //VmtDispatch + pos = MakeDword(pos); + } + //VmtDefaultHandler + pos = MakeDword(pos); + //VmtNewInstance + pos = MakeDword(pos); + //VmtFreeInstance + pos = MakeDword(pos); + //VmtDestroy + pos = MakeDword(pos); + //Vmt + int stopPos = Adr2Pos(GetStopAt(Pos2Adr(pos))); + //Virtual Methods + int ofs = 0; + while (pos < stopPos) + { + MakeComment(pos, "+" + Val2Str0(ofs)); ofs += 4; + pos = MakeDword(pos); + } +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::OutputVMTHeader(int pos, String vmtName) +{ + int fromPos = pos; + DWORD adr = Pos2Adr(pos); + + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"VMT_%lX_%s\", 0);\n", adr, adr, vmtName.c_str()); + //VmtSelfPtr + pos = MakeDword(pos); + return pos - fromPos; +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputIntfTable(int pos) +{ + MakeDword(pos); + DWORD intfTable = *((DWORD*)(Code + pos)); + if (intfTable) + { + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", intfTable); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_IntfTable\", 0);\n", intfTable, itemName.c_str()); + pos = Adr2Pos(intfTable); + //EntryCount + DWORD EntryCount = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + for (int n = 0; n < EntryCount; n++) + { + //GUID + pos = MakeArray(pos, 16); + //vTableAdr + OutputIntfVTable(pos, intfTable); pos += 4; + //IOffset + pos = MakeDword(pos); + if (DelphiVersion > 3) + { + //ImplGetter + pos = MakeDword(pos); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputIntfVTable(int pos, DWORD stopAdr) +{ + MakeDword(pos); + DWORD vTableAdr = *((DWORD*)(Code + pos)); + if (vTableAdr) + { + int pos = Adr2Pos(vTableAdr); + //CC byte address + DWORD CCadr = vTableAdr; + for (int n = 0;; n++) + { + if (Pos2Adr(pos) == stopAdr) break; + DWORD vAdr = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + MakeFunction(vAdr); + if (vAdr && vAdr < CCadr) CCadr = vAdr; + } + CCadr--; + MakeByte(Adr2Pos(CCadr)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputAutoTable(int pos) +{ + MakeDword(pos); + DWORD autoTable = *((DWORD*)(Code + pos)); + if (autoTable) + { + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", autoTable); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_AutoTable\", 0);\n", autoTable, itemName.c_str()); + pos = Adr2Pos(autoTable); + //EntryCount + DWORD EntryCount = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + for (int n = 0; n < EntryCount; n++) + { + //DispID + pos = MakeDword(pos); + //NameAdr + pos = MakeDword(pos); + //Flags + pos = MakeDword(pos); + //ParamsAdr + OutputAutoPTable(pos); pos += 4; + //ProcAdr + //DWORD procAdr = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + //MakeFunction(procAdr); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputAutoPTable(int pos) +{ + MakeDword(pos); + DWORD paramsAdr = *((DWORD*)(Code + pos)); + if (paramsAdr) + { + pos = Adr2Pos(paramsAdr); + BYTE paramCnt = Code[pos + 1]; + MakeArray(Adr2Pos(paramsAdr), paramCnt + 2); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputInitTable(int pos) +{ + MakeDword(pos); + DWORD initTable = *((DWORD*)(Code + pos)); + if (initTable) + { + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", initTable); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_InitTable\", 0);\n", initTable, itemName.c_str()); + pos = Adr2Pos(initTable); + //0xE + pos = MakeByte(pos); + //Unknown byte + pos = MakeByte(pos); + //Unknown dword + pos = MakeDword(pos); + //num + DWORD num = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + + for (int n = 0; n < num; n++) + { + //TypeOfs + pos = MakeDword(pos); + //FieldOfs + pos = MakeDword(pos); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputFieldTable(int pos) +{ + MakeDword(pos); + DWORD fieldTable = *((DWORD*)(Code + pos)); + if (fieldTable) + { + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", fieldTable); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_FieldTable\", 0);\n", fieldTable, itemName.c_str()); + pos = Adr2Pos(fieldTable); + //num + WORD num = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + //TypesTab + OutputFieldTTable(pos); pos += 4; + for (int n = 0; n < num; n++) + { + //Offset + pos = MakeDword(pos); + //Idx + pos = MakeWord(pos); + //Name + pos = MakeShortString(pos); + } + if (DelphiVersion >= 2010) + { + //num + num = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + + for (int n = 0; n < num; n++) + { + //Flags + pos = MakeByte(pos); + //TypeRef + pos = MakeDword(pos); + //Offset + pos = MakeDword(pos); + //Name + pos = MakeShortString(pos); + //AttrData + pos = OutputAttrData(pos); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputFieldTTable(int pos) +{ + MakeDword(pos); + DWORD typesTab = *((DWORD*)(Code + pos)); + if (typesTab) + { + pos = Adr2Pos(typesTab); + //num + WORD num = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + for (int n = 0; n < num; n++) + pos = MakeDword(pos); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputMethodTable(int pos) +{ + MakeDword(pos); + DWORD methodTable = *((DWORD*)(Code + pos)); + if (methodTable) + { + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", methodTable); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_MethodTable\", 0);\n", methodTable, itemName.c_str()); + pos = Adr2Pos(methodTable); + //Count + WORD count = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + + for (int n = 0; n < count; n++) + { + //Len + WORD len = *((WORD*)(Code + pos)); + int endpos = pos + len; + pos = MakeWord(pos); + //CodeAddress + //DWORD codeAdr = *((WORD*)(Code + pos)); + pos = MakeDword(pos); + //MakeFunction(codeAdr); + //Name + pos = MakeShortString(pos); + //Tail + if (pos < endpos) + { + OutputVmtMethodEntryTail(pos); + pos = endpos; + } + } + if (DelphiVersion >= 2010) + { + //ExCount + WORD excount = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + + for (int n = 0; n < excount; n++) + { + //Entry + OutputVmtMethodEntry(pos); pos += 4; + //Flags + pos = MakeWord(pos); + //VirtualIndex + pos = MakeWord(pos); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputVmtMethodEntry(int pos) +{ + MakeDword(pos); + DWORD entry = *((DWORD*)(Code + pos)); + if (entry) + { + pos = Adr2Pos(entry); + //Len + WORD len = *((WORD*)(Code + pos)); + int endpos = pos + len; + pos = MakeWord(pos); + //CodeAddress + //DWORD codeAdr = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + //MakeFunction(codeAdr); + //Name + pos = MakeShortString(pos); + //Tail + if (pos < endpos) + pos = OutputVmtMethodEntryTail(pos); + } +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::OutputVmtMethodEntryTail(int pos) +{ + //Version + pos = MakeByte(pos); + //CC + pos = MakeByte(pos); + //ResultType + pos = MakeDword(pos); + //ParOff + pos = MakeWord(pos); + //ParamCount + BYTE paramCnt = Code[pos]; + pos = MakeByte(pos); + + for (int n = 0; n < paramCnt; n++) + { + //Flags + pos = MakeByte(pos); + //ParamType + pos = MakeDword(pos); + //ParOff + pos = MakeWord(pos); + //Name + pos = MakeShortString(pos); + //AttrData + pos = OutputAttrData(pos); + } + //AttrData + return OutputAttrData(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputDynamicTable(int pos) +{ + MakeDword(pos); + DWORD dynamicTable = *((DWORD*)(Code + pos)); + if (dynamicTable) + { + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", dynamicTable); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_DynamicTable\", 0);\n", dynamicTable, itemName.c_str()); + pos = Adr2Pos(dynamicTable); + //Num + WORD num = *((WORD*)(Code + pos)); + pos = MakeWord(pos); + + for (int n = 0; n < num; n++) + { + //Msg + pos = MakeWord(pos); + } + for (int n = 0; n < num; n++) + { + //ProcAddress + pos = MakeDword(pos); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputResString(int pos, PInfoRec recN) +{ + itemName = recN->GetName(); + MakeComment(pos, itemName); + pos = MakeDword(pos); + pos = MakeDword(pos); +} +//--------------------------------------------------------------------------- +int __fastcall TIDCGen::OutputProc(int pos, PInfoRec recN, bool imp) +{ + itemName = recN->GetName(); + int fromPos = pos; + DWORD fromAdr = Pos2Adr(pos); + + if (itemName != "") + { + int idx = names->IndexOf(itemName); + if (idx == -1) + { + names->Add(itemName); + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", fromAdr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s\", 0x20);\n", fromAdr, itemName.c_str()); + //CurrentBytes += fprintf(idcF, "ApplyType(0x%lX, \"%s\", 0);\n", fromAdr, recN->MakeIDCPrototype(...)); + } + else + { + PREPNAMEINFO info = GetNameInfo(idx); + if (!info) + { + info = new REPNAMEINFO; + info->index = idx; + info->counter = 0; + repeated->Add((void*)info); + } + int cnt = info->counter; + info->counter++; + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", fromAdr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_%d\", 0x20);\n", fromAdr, itemName.c_str(), cnt); + //CurrentBytes += fprintf(idcF, "ApplyType(0x%lX, \"%s_%d\", 0);\n", fromAdr, recN->MakeIDCPrototype(...), cnt); + } + MakeComment(pos, recN->MakePrototype(fromAdr, true, false, false, true, false)); + } + int _procSize = GetProcSize(fromAdr); + //If no procedure just return 0; + if (!_procSize) return 0; + + int instrLen = MakeCode(pos); + if (imp || _procSize == instrLen) + { + CurrentBytes += fprintf(idcF, "MakeFunction(0x%lX, 0x%lX);\n", fromAdr, fromAdr + instrLen); + return instrLen - 1;//= procSize - 1 + } + + while (1) + { + if (pos - fromPos + 1 == _procSize) + { + CurrentBytes += fprintf(idcF, "MakeFunction(0x%lX, 0x%lX);\n", fromAdr, Pos2Adr(pos) + 1); + break; + } + + PInfoRec recN1 = GetInfoRec(Pos2Adr(pos)); + if (recN1 && recN1->picode) MakeComment(pos, FMain_11011981->MakeComment(recN1->picode)); + + if (IsFlagSet(cfExcept | cfFinally, pos)) + { + MakeCode(pos); + pos++; + continue; + } + + if (IsFlagSet(cfETable, pos)) + { + DWORD num = *((DWORD*)(Code + pos)); + pos = MakeDword(pos); + for (int n = 0; n < num; n++) + { + pos = MakeDword(pos); //ExceptionInfo + pos = MakeDword(pos); //ExceptionProc + } + continue; + } + if (IsFlagSet(cfLoc, pos) && (pos != fromPos)) + { + MakeCode(pos); + pos++; + continue; + } + pos++; + } + return pos - fromPos;//= procSize - 1 +} +//--------------------------------------------------------------------------- +void __fastcall TIDCGen::OutputData(int pos, PInfoRec recN) +{ + if (recN->HasName()) + { + MakeByte(pos); + if (recN->type == "" || + (!SameText(recN->type, "Single") && + !SameText(recN->type, "Double") && + !SameText(recN->type, "Extended") && + !SameText(recN->type, "Comp") && + !SameText(recN->type, "Currency"))) + { + String _name = recN->GetName(); + int idx = names->IndexOf(_name); + DWORD adr = Pos2Adr(pos); + if (idx == -1) + { + names->Add(_name); + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s\", 0);\n", adr, _name.c_str()); + } + else + { + PREPNAMEINFO info = GetNameInfo(idx); + if (!info) + { + info = new REPNAMEINFO; + info->index = idx; + info->counter = 0; + repeated->Add((void*)info); + } + int cnt = info->counter; + info->counter++; + CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); + CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_%d\", 0);\n", adr, _name.c_str(), cnt); + } + } + if (recN->type != "") MakeComment(pos, recN->type.c_str()); + } +} +//--------------------------------------------------------------------------- +PREPNAMEINFO __fastcall TIDCGen::GetNameInfo(int idx) +{ + int num = repeated->Count; + for (int n = 0; n < num; n++) + { + PREPNAMEINFO info = (PREPNAMEINFO)repeated->Items[n]; + if (info->index == idx) return info; + } + return 0; +} +//--------------------------------------------------------------------------- +__fastcall TSaveIDCDialog::TSaveIDCDialog(TComponent* AOwner, char* TemplateName) : TSaveDialog(AOwner) +{ + Options >> ofEnableSizing; + Template = TemplateName; + CheckDlgButton(Handle, 101, SplitIDC ? BST_CHECKED : BST_UNCHECKED); +} +//--------------------------------------------------------------------------- +void __fastcall TSaveIDCDialog::WndProc(TMessage& Message) +{ + switch (Message.Msg) + { + case WM_COMMAND: + switch (Message.WParamLo) + { + case 101: + if (IsDlgButtonChecked(Handle, 101) == BST_CHECKED) + SplitIDC = true; + else + SplitIDC = false; + break; + }; + break; + }; + TOpenDialog::WndProc(Message); +}; +//--------------------------------------------------------------------------- diff --git a/IDCGen.h b/IDCGen.h new file mode 100644 index 0000000..d85ca71 --- /dev/null +++ b/IDCGen.h @@ -0,0 +1,95 @@ +//--------------------------------------------------------------------------- +#ifndef IDCGenH +#define IDCGenH + +#include "Main.h" + +typedef struct +{ + int index; //Index of name in names + int counter; //Counter +} REPNAMEINFO, *PREPNAMEINFO; + +class TIDCGen +{ +public: + __fastcall TIDCGen(FILE* FIdc, int splitSize); + __fastcall ~TIDCGen(); + void __fastcall NewIDCPart(FILE* FIdc); + void __fastcall DeleteName(int pos); + int __fastcall MakeByte(int pos); + int __fastcall MakeWord(int pos); + int __fastcall MakeDword(int pos); + int __fastcall MakeQword(int pos); + int __fastcall MakeArray(int pos, int num); + int __fastcall MakeShortString(int pos); + int __fastcall MakeCString(int pos); + void __fastcall MakeLString(int pos); + void __fastcall MakeWString(int pos); + void __fastcall MakeUString(int pos); + int __fastcall MakeCode(int pos); + void __fastcall MakeFunction(DWORD adr); + void __fastcall MakeComment(int pos, String text); + int __fastcall OutputAttrData(int pos); + void __fastcall OutputHeaderFull(); + void __fastcall OutputHeaderShort(); + int __fastcall OutputRTTIHeader(BYTE kind, int pos); + void __fastcall OutputRTTIInteger(BYTE kind, int pos); + void __fastcall OutputRTTIChar(BYTE kind, int pos); + void __fastcall OutputRTTIEnumeration(BYTE kind, int pos, DWORD adr); + void __fastcall OutputRTTIFloat(BYTE kind, int pos); + void __fastcall OutputRTTIString(BYTE kind, int pos); + void __fastcall OutputRTTISet(BYTE kind, int pos); + void __fastcall OutputRTTIClass(BYTE kind, int pos); + void __fastcall OutputRTTIMethod(BYTE kind, int pos); + void __fastcall OutputRTTIWChar(BYTE kind, int pos); + void __fastcall OutputRTTILString(BYTE kind, int pos); + void __fastcall OutputRTTIWString(BYTE kind, int pos); + void __fastcall OutputRTTIVariant(BYTE kind, int pos); + void __fastcall OutputRTTIArray(BYTE kind, int pos); + void __fastcall OutputRTTIRecord(BYTE kind, int pos); + void __fastcall OutputRTTIInterface(BYTE kind, int pos); + void __fastcall OutputRTTIInt64(BYTE kind, int pos); + void __fastcall OutputRTTIDynArray(BYTE kind, int pos); + void __fastcall OutputRTTIUString(BYTE kind, int pos); + void __fastcall OutputRTTIClassRef(BYTE kind, int pos); + void __fastcall OutputRTTIPointer(BYTE kind, int pos); + void __fastcall OutputRTTIProcedure(BYTE kind, int pos); + void __fastcall OutputVMT(int pos, PInfoRec recN); + int __fastcall OutputVMTHeader(int pos, String vmtName); + void __fastcall OutputIntfTable(int pos); + void __fastcall OutputIntfVTable(int pos, DWORD stopAdr); + void __fastcall OutputAutoTable(int pos); + void __fastcall OutputAutoPTable(int pos); + void __fastcall OutputInitTable(int pos); + void __fastcall OutputFieldTable(int pos); + void __fastcall OutputFieldTTable(int pos); + void __fastcall OutputMethodTable(int pos); + void __fastcall OutputVmtMethodEntry(int pos); + int __fastcall OutputVmtMethodEntryTail(int pos); + void __fastcall OutputDynamicTable(int pos); + void __fastcall OutputResString(int pos, PInfoRec recN); + int __fastcall OutputProc(int pos, PInfoRec recN, bool imp); + void __fastcall OutputData(int pos, PInfoRec recN); + PREPNAMEINFO __fastcall GetNameInfo(int idx); + FILE* idcF; + String unitName; + String itemName; + TStringList* names; + TList* repeated; + int SplitSize;//Maximum output bytes if idc splitted + int CurrentPartNo;//Current part number (filename looks like XXX_NN.idc) + int CurrentBytes;//Current part output bytes +}; + +class TSaveIDCDialog : public TSaveDialog +{ +public: + __fastcall TSaveIDCDialog(TComponent* AOwner, char* TemplateName); +protected: + virtual void __fastcall WndProc(Messages::TMessage &Message); +}; +//--------------------------------------------------------------------------- +#endif + + diff --git a/Dll/Icons.dll b/Icons.dll similarity index 100% rename from Dll/Icons.dll rename to Icons.dll diff --git a/IdcDialog.rc b/IdcDialog.rc new file mode 100644 index 0000000..753f360 --- /dev/null +++ b/IdcDialog.rc @@ -0,0 +1,7 @@ +SAVEIDCDLG DIALOG 0, 0, 260, 42 +STYLE DS_3DLOOK | DS_CONTROL | DS_CONTEXTHELP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU +CAPTION "" +FONT 8, "MS Sans Serif" +begin + CONTROL "Split output", 101, "button", BS_AUTOCHECKBOX | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 32, 16, 80, 16 +end diff --git a/IdcDialog.res b/IdcDialog.res new file mode 100644 index 0000000..667204c Binary files /dev/null and b/IdcDialog.res differ diff --git a/IdcSplitSize.cpp b/IdcSplitSize.cpp new file mode 100644 index 0000000..a1b75c5 --- /dev/null +++ b/IdcSplitSize.cpp @@ -0,0 +1,35 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "IdcSplitSize.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +extern int SplitSize; + +TFIdcSplitSize *FIdcSplitSize; +//--------------------------------------------------------------------- +__fastcall TFIdcSplitSize::TFIdcSplitSize(TComponent* AOwner) + : TForm(AOwner) +{ + Caption = "Split size: 1 Mbyte"; +} +//--------------------------------------------------------------------- +void __fastcall TFIdcSplitSize::OKBtnClick(TObject *Sender) +{ + SplitSize = (1 << (tbSplitSize->Position + 19));//MBytes + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFIdcSplitSize::CancelBtnClick(TObject *Sender) +{ + SplitSize = 0; + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFIdcSplitSize::tbSplitSizeChange(TObject *Sender) +{ + Caption = "Split size: " + String(tbSplitSize->Position) + " MByte"; +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/IdcSplitSize.dfm b/IdcSplitSize.dfm similarity index 85% rename from Sources/Forms/IdcSplitSize.dfm rename to IdcSplitSize.dfm index 9b5d259..4b01b04 100644 --- a/Sources/Forms/IdcSplitSize.dfm +++ b/IdcSplitSize.dfm @@ -45,10 +45,15 @@ object FIdcSplitSize: TFIdcSplitSize Width = 281 Height = 45 Min = 1 + Orientation = trHorizontal PageSize = 1 + Frequency = 1 Position = 1 + SelEnd = 0 + SelStart = 0 TabOrder = 2 TickMarks = tmTopLeft + TickStyle = tsAuto OnChange = tbSplitSizeChange end end diff --git a/IdcSplitSize.h b/IdcSplitSize.h new file mode 100644 index 0000000..164181d --- /dev/null +++ b/IdcSplitSize.h @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------------- +#ifndef IdcSplitSizeH +#define IdcSplitSizeH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TFIdcSplitSize : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TBevel *Bevel1; + TTrackBar *tbSplitSize; + void __fastcall OKBtnClick(TObject *Sender); + void __fastcall CancelBtnClick(TObject *Sender); + void __fastcall tbSplitSizeChange(TObject *Sender); +private: +public: + virtual __fastcall TFIdcSplitSize(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFIdcSplitSize *FIdcSplitSize; +//---------------------------------------------------------------------------- +#endif diff --git a/Idr.bpr b/Idr.bpr new file mode 100644 index 0000000..54d02cf --- /dev/null +++ b/Idr.bpr @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=2 +MinorVer=6 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1049 +CodePage=1251 + +[Version Info Keys] +CompanyName= +FileDescription=Interactive Delphi Reconstructor +FileVersion=2.6.0.0 +InternalName=IDR +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=2.5.0.121 +Comments= + +[Excluded Packages] +c:\program files (x86)\borland\cbuilder6\Bin\dclqrt60.bpl=QuickReport Components +C:\Windows\SysWOW64\ibevnt60.bpl=Borland Interbase Event Alerter Component +c:\program files (x86)\borland\cbuilder6\Bin\dcltee60.bpl=TeeChart Components +c:\program files (x86)\borland\cbuilder6\Bin\dcltqr60.bpl=TeeChart for QuickReport Components +c:\program files (x86)\borland\cbuilder6\Bin\dclib60.bpl=InterBase Data Access Components +c:\program files (x86)\borland\cbuilder6\Bin\dclclxdb60.bpl=Borland CLX Database Components +C:\Program Files (x86)\Borland\CBuilder6\Bin\dclclxstd60.bpl=Borland CLX Standard Components +c:\program files (x86)\borland\cbuilder6\Bin\dclnet60.bpl=Borland Internet Components +c:\program files (x86)\borland\cbuilder6\Bin\DBWEBXPRT.BPL=Borland Web Wizard Package +c:\program files (x86)\borland\cbuilder6\Bin\DCLNMF60.bpl=NetMasters Fastnet Tools +c:\program files (x86)\borland\cbuilder6\Bin\dclsoap60.bpl=Borland SOAP Components +c:\program files (x86)\borland\cbuilder6\Bin\dcldbx60.bpl=Borland dbExpress Components +c:\program files (x86)\borland\cbuilder6\Bin\dcldbxcds60.bpl=Borland Local DBX ClientDataset Components +c:\program files (x86)\borland\cbuilder6\Bin\dclite60.bpl=Borland Integrated Translation Environment + +[HistoryLists\hlIncludePath] +Count=19 +Item0=UnicodeControls;C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item1=C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item2=C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;Projects;..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item3=Projects;..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item4=..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item5=C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item6=C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item7=$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item8=C:\LMD2010\lib\b6;..\..\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item9=..\..\Bin;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\Source\vcl +Item10=C:\PROGRAM FILES\BORLAND\CBUILDER6\OBJREPOS;C:\Program Files\Borland\CBuilder6\Bin;c:\program files\borland\cbuilder6\source\vcl;$(BCB)\include;$(BCB)\include\vcl +Item11=C:\Program Files\Borland\CBuilder6\Bin;c:\program files\borland\cbuilder6\source\vcl;$(BCB)\include;$(BCB)\include\vcl +Item12=c:\program files\borland\cbuilder6\source\vcl;$(BCB)\include;$(BCB)\include\vcl +Item13=c:\program files\borland\cbuilder6\source\vcl;C:\Program Files\Borland\CBuilder6\Projects;C:\Program Files\Borland\CBuilder5\bin;$(BCB)\include;$(BCB)\include\vcl +Item14=C:\Program Files\Borland\CBuilder6\Projects;C:\Program Files\Borland\CBuilder5\bin;$(BCB)\include;$(BCB)\include\vcl +Item15=C:\Program Files\Borland\CBuilder5\bin;$(BCB)\include;$(BCB)\include\vcl +Item16=C:\Program Files\Borland\CBuilder5\bin\;$(BCB)\include;$(BCB)\include\vcl +Item17=$(BCB)\include;$(BCB)\include\vcl +Item18=C:\Program Files\Borland\CBuilder5\Components\AdvStringGrid;$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=20 +Item0=UnicodeControls;c:\program files (x86)\borland\cbuilder6\source\vcl;C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item1=c:\program files (x86)\borland\cbuilder6\source\vcl;C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item2=c:\program files (x86)\borland\cbuilder6\source\vcl;C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;Projects;..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item3=C:\PROGRAM FILES (X86)\BORLAND\CBUILDER6\OBJREPOS;Projects;..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item4=Projects;..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item5=..\SE4\SE4_Project;C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item6=C:\Program Files (x86)\Borland\CBuilder6\Bin;C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item7=C:\Program Files\Borland\CBuilder6\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item8=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item9=$(BCB)\Projects\Lib;C:\LMD2010\lib\b6;..\..\Bin;$(BCB)\lib\obj;$(BCB)\lib +Item10=..\..\Bin;$(BCB)\lib\obj;$(BCB)\lib +Item11=$(BCB)\lib\obj;$(BCB)\lib +Item12=C:\PROGRAM FILES\BORLAND\CBUILDER6\OBJREPOS;C:\Program Files\Borland\CBuilder6\Bin;c:\program files\borland\cbuilder6\source\vcl;$(BCB)\lib\obj;$(BCB)\lib +Item13=C:\Program Files\Borland\CBuilder6\Bin;c:\program files\borland\cbuilder6\source\vcl;$(BCB)\lib\obj;$(BCB)\lib +Item14=c:\program files\borland\cbuilder6\source\vcl;$(BCB)\lib\obj;$(BCB)\lib +Item15=c:\program files\borland\cbuilder6\source\vcl;C:\Program Files\Borland\CBuilder6\Projects;C:\Program Files\Borland\CBuilder5\bin;$(BCB)\lib\obj;$(BCB)\lib +Item16=C:\Program Files\Borland\CBuilder6\Projects;C:\Program Files\Borland\CBuilder5\bin;$(BCB)\lib\obj;$(BCB)\lib +Item17=C:\Program Files\Borland\CBuilder5\bin;$(BCB)\lib\obj;$(BCB)\lib +Item18=C:\Program Files\Borland\CBuilder5\bin\;$(BCB)\lib\obj;$(BCB)\lib +Item19=C:\Program Files\Borland\CBuilder5\Components\AdvStringGrid;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=1 +Item0=_DEBUG + +[HistoryLists\hlIntOutputDir] +Count=2 +Item0=obj +Item1=C:\Program Files\Borland\CBuilder6\Projects\IDR + +[HistoryLists\hlFinalOutputDir] +Count=6 +Item0=C:\PAPA\IDR\ +Item1=C:\PAPA\IDR +Item2=C:\PAPA\IDR\bin\ +Item3=C:\PAPA\IDR\bin +Item4=G:\IDR\ +Item5=G:\IDR + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +Launcher= +UseLauncher=0 +DebugCWD= +HostApplication= +RemoteHost= +RemotePath= +RemoteLauncher= +RemoteCWD= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=1 +LinkCGLIB=0 + + \ No newline at end of file diff --git a/Idr.cbproj b/Idr.cbproj deleted file mode 100644 index dce3f0c..0000000 --- a/Idr.cbproj +++ /dev/null @@ -1,853 +0,0 @@ - - - {A4002B6A-1D56-4589-804C-C8EF20F404D3} - 18.2 - VCL - Application - Idr.cpp - True - Debug - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - JPHNE - true - .\$(Platform)\$(Config)\Obj - .\$(Platform)\$(Config)\Bin - false - true - true - $(BDSLIB)\$(PLATFORM)\release\$(LANGDIR);$(ILINK_TranslatedLibraryPath) - CppVCLApplication - DataSnapIndy10ServerTransport;bindcompfmx;DBXSqliteDriver;vcldbx;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;bindcomp;inetdb;vclib;inetdbbde;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DBXOdbcDriver;DataSnapServer;DataSnapProviderClient;xmlrtl;DBXSybaseASEDriver;ibxpress;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;DatasnapConnectorsFreePascal;MetropolisUILiveTile;soaprtl;vclactnband;bindengine;vcldb;bindcompdbx;vcldsnap;bindcompvcl;vclie;vcltouch;DBXDb2Driver;bcbsmp;DBXOracleDriver;CustomIPTransport;vclribbon;VclSmp;dsnap;IndyIPServer;DBXInformixDriver;fmxase;vcl;IndyCore;DataSnapConnectors;IndyIPCommon;CloudService;DBXMSSQLDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;vclx;inetdbxpress;svn;DBXSybaseASADriver;fmxdae;bdertl;dbexpress;bcbie;adortl;IndyIPClient;$(PackageImports) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - vcl.lib;rtl.lib;bcbsmp.lib;vclx.lib;vclimg.lib - <_TCHARMapping>char - true - $(BDS)\bin\cbuilder_PROJECTICON.ico - $(BDS)\bin\Artwork\Windows\UWP\cppreg_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\cppreg_UwpDefault_150.png - Idr - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - Sources\Libs\;Sources\Forms\;Sources\;$(IncludePath) - Sources\Libs\;Sources\Forms\;Sources\;$(ILINK_LibraryPath) - true - - - - $(BDSINCLUDE)\windows\vcl;$(IncludePath) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true - $(BDS)\bin\default_app.manifest - - - $(BDSINCLUDE)\windows\vcl;$(IncludePath) - - - false - true - false - true - _DEBUG;$(Defines) - false - None - DEBUG - true - true - true - Full - true - true - true - true - true - $(BDSLIB)\$(PLATFORM)\debug;$(ILINK_LibraryPath) - $(BDSLIB)\$(PLATFORM)\debug\$(LANGDIR);$(ILINK_TranslatedLibraryPath) - true - - - true - true - vcl.bpi;rtl.bpi;bcbsmp.bpi;vclx.bpi;vclimg.bpi - Images\idr.ico - true - - - NDEBUG;$(Defines) - None - - - true - true - rtl.bpi;vcl.bpi;vclimg.bpi;vclx.bpi - true - - - - 0 - - - 1 - true - - -
FAboutDlg_11011981
- dfm - Sources\Forms\AboutDlg.h - 3 -
- -
FActiveProcesses
- dfm - Sources\Forms\ActiveProcesses.h - 24 -
- -
FEditFieldsDlg_11011981
- dfm - Sources\Forms\EditFieldsDlg.h - 18 -
- -
FEditFunctionDlg_11011981
- dfm - Sources\Forms\EditFunctionDlg.h - 17 -
- -
FExplorer_11011981
- dfm - Sources\Forms\Explorer.h - 15 -
- -
FindDlg_11011981
- dfm - Sources\Forms\FindDlg.h - 14 -
- -
FHex2DoubleDlg_11011981
- dfm - Sources\Forms\Hex2Double.h - 22 -
- -
FIdcSplitSize
- dfm - Sources\Forms\IdcSplitSize.h - 21 -
- -
FInputDlg_11011981
- dfm - Sources\Forms\InputDlg.h - 12 -
- -
FKBViewer_11011981
- dfm - Sources\Forms\KBViewer.h - 16 -
- -
FLegend_11011981
- dfm - Sources\Forms\Legend.h - 19 -
- -
FMain_11011981
- dfm - Sources\Forms\Main.h - 25 -
- -
FPlugins
- dfm - Sources\Forms\Plugins.h - 23 -
- -
FProgressBar
- dfm - Sources\Forms\ProgressBar.h - 28 -
- -
FStringInfo_11011981
- dfm - Sources\Forms\StringInfo.h - 13 -
- -
FTypeInfo_11011981
- dfm - Sources\Forms\TypeInfo2.h - 26 -
- -
IdrDfmFormTree_11011981
- dfm - Sources\Forms\UfrmFormTree.h - 10 -
- - Sources\Libs\Decompiler.h - 5 - - - Sources\Libs\Disasm.h - 6 - - - Sources\Libs\IDCGen.h - 20 - - - Sources\Libs\Infos.h - 7 - - - Sources\Libs\KnowledgeBase.h - 8 - - - Sources\Libs\Misc.h - 4 - - - Sources\Libs\PEHeader.h - 29 - - - Sources\Libs\ProcessManager.h - 28 - - - Sources\Libs\Resources.h - 9 - - - Sources\Libs\Singleton.h - 30 - - - Sources\Libs\Threads.h - 27 - - - Sources\Libs\UFileDropper.h - 11 - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - CPlusPlusBuilder.Personality.12 - CppVCLApplication - - - - False - True - True - False - - - Idr.cpp - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - - - true - - - - - true - - - - - true - - - - - Idr.exe - true - - - - - true - - - - - true - - - - - Idr.tds - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - 1 - - - Contents\MacOS - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - - - res\values - 1 - - - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - - - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - Contents\MacOS - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - Contents\Resources\StartUp\ - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - 1 - - - 1 - - - - - ..\ - 1 - - - ..\ - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\ - 1 - - - - - Contents - 1 - - - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - True - False - - - 12 - - - - - - - False - - False - XCOPY /Y /E /H "$(PROJECTDIR)\Dll" "$(OUTPUTDIR)" - False - - - - False - - False - XCOPY /Y /E /H "$(PROJECTDIR)\Dll" "$(OUTPUTDIR)" - False - - - - False - - False - XCOPY /Y /E /H "$(PROJECTDIR)\Dll" "$(OUTPUTDIR)" - False - - - - False - - False - XCOPY /Y /E /H "$(PROJECTDIR)\Dll" "$(OUTPUTDIR)" - False - -
diff --git a/Idr.cpp b/Idr.cpp index bbbb93c..efd45fa 100644 --- a/Idr.cpp +++ b/Idr.cpp @@ -1,63 +1,57 @@ -// --------------------------------------------------------------------------- - +//--------------------------------------------------------------------------- #include #pragma hdrstop -#include -// --------------------------------------------------------------------------- -#include -#include -USEFORM("Sources\Forms\UfrmFormTree.cpp", IdrDfmFormTree_11011981); -USEFORM("Sources\Forms\ProgressBar.cpp", FProgressBar); -USEFORM("Sources\Forms\StringInfo.cpp", FStringInfo_11011981); -USEFORM("Sources\Forms\TypeInfo2.cpp", FTypeInfo_11011981); -USEFORM("Sources\Forms\EditFieldsDlg.cpp", FEditFieldsDlg_11011981); -USEFORM("Sources\Forms\EditFunctionDlg.cpp", FEditFunctionDlg_11011981); -USEFORM("Sources\Forms\Explorer.cpp", FExplorer_11011981); -USEFORM("Sources\Forms\ActiveProcesses.cpp", FActiveProcesses); -USEFORM("Sources\Forms\AboutDlg.cpp", FAboutDlg_11011981); -USEFORM("Sources\Forms\FindDlg.cpp", FindDlg_11011981); -USEFORM("Sources\Forms\Legend.cpp", FLegend_11011981); -USEFORM("Sources\Forms\Main.cpp", FMain_11011981); -USEFORM("Sources\Forms\Plugins.cpp", FPlugins); -USEFORM("Sources\Forms\KBViewer.cpp", FKBViewer_11011981); -USEFORM("Sources\Forms\Hex2Double.cpp", FHex2DoubleDlg_11011981); -USEFORM("Sources\Forms\IdcSplitSize.cpp", FIdcSplitSize); -USEFORM("Sources\Forms\InputDlg.cpp", FInputDlg_11011981); +#include "SyncObjs.hpp" + +USEFORM("Main.cpp", FMain_11011981); +USEFORM("TypeInfo.cpp", FTypeInfo_11011981); +USEFORM("StringInfo.cpp", FStringInfo_11011981); +USEFORM("Explorer.cpp", FExplorer_11011981); +USEFORM("InputDlg.cpp", FInputDlg_11011981); +USEFORM("FindDlg.cpp", FindDlg_11011981); +USEFORM("EditFunctionDlg.cpp", FEditFunctionDlg_11011981); +USEFORM("AboutDlg.cpp", FAboutDlg_11011981); +USEFORM("EditFieldsDlg.cpp", FEditFieldsDlg_11011981); +USEFORM("KBViewer.cpp", FKBViewer_11011981); +USEFORM("UfrmFormTree.cpp", IdrDfmFormTree_11011981); +USEFORM("Legend.cpp", FLegend_11011981); +USEFORM("Hex2Double.cpp", FHex2DoubleDlg_11011981); +USEFORM("Plugins.cpp", FPlugins); +USEFORM("ActiveProcesses.cpp", FActiveProcesses); +USEFORM("IdcSplitSize.cpp", FIdcSplitSize); +USEFORM("ProgressBar.cpp", FProgressBar); //--------------------------------------------------------------------------- -int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) { - try { - Application->Initialize(); - Application->MainFormOnTaskBar = true; - Application->CreateForm(__classid(TFMain_11011981), &FMain_11011981); - Application->CreateForm(__classid(TFExplorer_11011981), &FExplorer_11011981); - Application->CreateForm(__classid(TFTypeInfo_11011981), &FTypeInfo_11011981); - Application->CreateForm(__classid(TFStringInfo_11011981), &FStringInfo_11011981); - Application->CreateForm(__classid(TFInputDlg_11011981), &FInputDlg_11011981); - Application->CreateForm(__classid(TFindDlg_11011981), &FindDlg_11011981); - Application->CreateForm(__classid(TFEditFunctionDlg_11011981), &FEditFunctionDlg_11011981); - Application->CreateForm(__classid(TFEditFieldsDlg_11011981), &FEditFieldsDlg_11011981); - Application->CreateForm(__classid(TFAboutDlg_11011981), &FAboutDlg_11011981); - Application->CreateForm(__classid(TFKBViewer_11011981), &FKBViewer_11011981); - Application->CreateForm(__classid(TFLegend_11011981), &FLegend_11011981); - Application->CreateForm(__classid(TFHex2DoubleDlg_11011981), &FHex2DoubleDlg_11011981); - Application->CreateForm(__classid(TFPlugins), &FPlugins); - Application->CreateForm(__classid(TFActiveProcesses), &FActiveProcesses); - Application->CreateForm(__classid(TFIdcSplitSize), &FIdcSplitSize); - Application->CreateForm(__classid(TFProgressBar), &FProgressBar); - Application->Run(); - } - catch (Exception &exception) { - Application->ShowException(&exception); - } - catch (...) { - try { - throw Exception(""); - } - catch (Exception &exception) { - Application->ShowException(&exception); - } - } - return 0; +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + try + { + Randomize(); + Application->Initialize(); + Application->HelpFile = ""; + Application->CreateForm(__classid(TFMain_11011981), &FMain_11011981); + Application->CreateForm(__classid(TFExplorer_11011981), &FExplorer_11011981); + Application->CreateForm(__classid(TFTypeInfo_11011981), &FTypeInfo_11011981); + Application->CreateForm(__classid(TFStringInfo_11011981), &FStringInfo_11011981); + Application->CreateForm(__classid(TFInputDlg_11011981), &FInputDlg_11011981); + Application->CreateForm(__classid(TFindDlg_11011981), &FindDlg_11011981); + Application->CreateForm(__classid(TFEditFunctionDlg_11011981), &FEditFunctionDlg_11011981); + Application->CreateForm(__classid(TFEditFieldsDlg_11011981), &FEditFieldsDlg_11011981); + Application->CreateForm(__classid(TFAboutDlg_11011981), &FAboutDlg_11011981); + Application->CreateForm(__classid(TFKBViewer_11011981), &FKBViewer_11011981); + Application->CreateForm(__classid(TFLegend_11011981), &FLegend_11011981); + Application->CreateForm(__classid(TFHex2DoubleDlg_11011981), &FHex2DoubleDlg_11011981); + Application->CreateForm(__classid(TFPlugins), &FPlugins); + Application->CreateForm(__classid(TFActiveProcesses), &FActiveProcesses); + Application->CreateForm(__classid(TFIdcSplitSize), &FIdcSplitSize); + Application->CreateForm(__classid(TFProgressBar), &FProgressBar); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + return 0; } -// --------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + diff --git a/Idr.ini b/Idr.ini new file mode 100644 index 0000000..ad45751 --- /dev/null +++ b/Idr.ini @@ -0,0 +1,38 @@ +[MainForm] +Left=-8 +Top=-8 +Width=1296 +Height=1040 +CXRefWidth=180 +SXRefWidth=128 +CXrefsWidth=154 +SXrefsWidth=128 +LeftWidth=281 +BottomHeight=173 +WorkingDir=G:\DELPHI\WonderlandOnline +[Recent Executable Files] +File1="G:\DELPHI\WonderlandOnline\aLogin.exe",5 +File2="G:\DELPHI\TEST\D7\Auto5.exe",7 +File3="G:\DELPHI\TEST\D2\totalcmd750a.exe",2 +File4="G:\DELPHI\TEST\D7\BC2.exe",7 +File5="G:\DELPHI\Solver\Solver.exe",7 +File6="G:\DELPHI\Delphi2\VolAdj.exe",2 +File7="G:\DELPHI\PVP\CrearDB.exe",6 +File8="G:\DELPHI\PVP\Utiles.dll",6 +[Recent Project Files] +File5="G:\DELPHI\main_old.idp" +File7="G:\DELPHI\TEST\D4\Beyond32\Beyond32.idp" +File8="C:\temp\RegDelReflector.idp" +File4="C:\PAPA\SE4\Se4.idp" +File3="C:\SGTaller 2\Modulos\PVP\PVP.idp" +File2="G:\DELPHI\PVP\PVP.idp" +File6="G:\Andy\new\Project1.idp" +File1="G:\DELPHI\WonderlandOnline\aLogin.idp" +[Settings] +CodePage=950 +FontName=Courier New +FontSize=12 +FontColor=0 +FontBold=1 +FontCharset=204 +FontItalic=0 diff --git a/Idr.res b/Idr.res new file mode 100644 index 0000000..93824dc Binary files /dev/null and b/Idr.res differ diff --git a/IdrPCH1.h b/IdrPCH1.h deleted file mode 100644 index 6027efd..0000000 --- a/IdrPCH1.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include diff --git a/Infos.cpp b/Infos.cpp new file mode 100644 index 0000000..f0b3d69 --- /dev/null +++ b/Infos.cpp @@ -0,0 +1,2947 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include "Infos.h" +#include "Main.h" +#include "Misc.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +//--------------------------------------------------------------------------- +extern MDisasm Disasm; +extern int MaxBufLen; +extern DWORD CodeBase; +extern DWORD *Flags; +extern PInfoRec *Infos; +extern BYTE *Code; +extern TCriticalSection* CrtSection; +extern MKnowledgeBase KnowledgeBase; +extern char StringBuf[MAXSTRBUFFER]; +//as some statistics for memory leaks detection (remove it when fixed) +long stat_InfosOverride = 0; +//--------------------------------------------------------------------------- +__fastcall InfoVmtInfo::InfoVmtInfo() +{ + interfaces = 0; + fields = 0; + methods = 0; +} +//--------------------------------------------------------------------------- +__fastcall InfoVmtInfo::~InfoVmtInfo() +{ + if (interfaces) delete interfaces; + CleanupList(fields); + CleanupList(methods); +} +//--------------------------------------------------------------------------- +void __fastcall InfoVmtInfo::AddInterface(String Value) +{ + if (!interfaces) interfaces = new TStringList; + interfaces->Add(Value); +} +//--------------------------------------------------------------------------- +PFIELDINFO __fastcall InfoVmtInfo::AddField(DWORD ProcAdr, int ProcOfs, BYTE Scope, int Offset, int Case, String Name, String Type) +{ + PFIELDINFO fInfo = 0; + + if (!fields) fields = new TList; + if (!fields->Count) + { + fInfo = new FIELDINFO; + fInfo->Scope = Scope; + fInfo->Offset = Offset; + fInfo->Case = Case; + fInfo->xrefs = 0; + fInfo->Name = Name; + fInfo->Type = Type; + fields->Add((void*)fInfo); + return fInfo; + } + + int F = 0, L = fields->Count - 1; + while (F < L) + { + int M = (F + L)/2; + fInfo = (PFIELDINFO)fields->Items[M]; + if (Offset <= fInfo->Offset) + L = M; + else + F = M + 1; + } + fInfo = (PFIELDINFO)fields->Items[L]; + if (fInfo->Offset != Offset) + { + fInfo = new FIELDINFO; + fInfo->Scope = Scope; + fInfo->Offset = Offset; + fInfo->Case = Case; + fInfo->xrefs = 0; + fInfo->Name = Name; + fInfo->Type = Type; + fields->Add((void*)fInfo); + fields->Sort(FieldsCmpFunction); + } + else + { + if (fInfo->Name == "") + fInfo->Name = Name; + if (fInfo->Type == "") + fInfo->Type = Type; + } + return fInfo; +} +//--------------------------------------------------------------------------- +void __fastcall InfoVmtInfo::RemoveField(int Offset) +{ + PFIELDINFO fInfo; + + if (!fields || !fields->Count) return; + int F = 0, L = fields->Count - 1; + while (F < L) + { + int M = (F + L)/2; + fInfo = (PFIELDINFO)fields->Items[M]; + if (Offset <= fInfo->Offset) + L = M; + else + F = M + 1; + } + + fInfo = (PFIELDINFO)fields->Items[L]; + if (fInfo->Offset == Offset) fields->Delete(L); +} +//--------------------------------------------------------------------------- +bool __fastcall InfoVmtInfo::AddMethod(bool Abstract, char Kind, int Id, DWORD Address, String Name) +{ + PMethodRec recM; + + if (!methods) methods = new TList; + + for (int n = 0; n < methods->Count; n++) + { + recM = (PMethodRec)methods->Items[n]; + if (Kind == 'A' || Kind == 'V') + { + if (recM->kind == Kind && recM->id == Id) + { + if (recM->name == ""&& Name != "") recM->name = Name; + return false; + } + } + else + { + if (recM->kind == Kind && recM->address == Address) + { + if (recM->name == "" && Name != "") recM->name = Name; + return false; + } + } + } + + recM = new MethodRec; + recM->abstract = Abstract; + recM->kind = Kind; + recM->id = Id; + recM->address = Address; + recM->name = Name; + methods->Add((void*)recM); + return true; +} +//--------------------------------------------------------------------------- +_fastcall InfoProcInfo::InfoProcInfo() +{ + flags = 0; + bpBase = 0; + retBytes = 0; + procSize = 0; + stackSize = 0; + args = 0; + locals = 0; +} +//--------------------------------------------------------------------------- +__fastcall InfoProcInfo::~InfoProcInfo() +{ + CleanupList(args); + CleanupList(locals); +} +//--------------------------------------------------------------------------- +PARGINFO __fastcall InfoProcInfo::AddArg(PARGINFO aInfo) +{ + return AddArg(aInfo->Tag, aInfo->Ndx, aInfo->Size, aInfo->Name, aInfo->TypeDef); +} +//--------------------------------------------------------------------------- +PARGINFO __fastcall InfoProcInfo::AddArg(BYTE Tag, int Ofs, int Size, String Name, String TypeDef) +{ + PARGINFO argInfo; + if (!args) args = new TList; + if (!args->Count) + { + argInfo = new ARGINFO; + argInfo->Tag = Tag; + argInfo->Register = false; + argInfo->Ndx = Ofs; + argInfo->Size = Size; + argInfo->Name = Name; + argInfo->TypeDef = TypeDef; + args->Add((void*)argInfo); + return argInfo; + } + + int F = 0; + argInfo = (PARGINFO)args->Items[F]; + if (Ofs < argInfo->Ndx) + { + argInfo = new ARGINFO; + argInfo->Tag = Tag; + argInfo->Register = false; + argInfo->Ndx = Ofs; + argInfo->Size = Size; + argInfo->Name = Name; + argInfo->TypeDef = TypeDef; + args->Insert(F, (void*)argInfo); + return argInfo; + } + int L = args->Count - 1; + argInfo = (PARGINFO)args->Items[L]; + if (Ofs > argInfo->Ndx) + { + argInfo = new ARGINFO; + argInfo->Tag = Tag; + argInfo->Register = false; + argInfo->Ndx = Ofs; + argInfo->Size = Size; + argInfo->Name = Name; + argInfo->TypeDef = TypeDef; + args->Add((void*)argInfo); + return argInfo; + } + while (F < L) + { + int M = (F + L)/2; + argInfo = (PARGINFO)args->Items[M]; + if (Ofs <= argInfo->Ndx) + L = M; + else + F = M + 1; + } + argInfo = (PARGINFO)args->Items[L]; + if (argInfo->Ndx != Ofs) + { + argInfo = new ARGINFO; + argInfo->Tag = Tag; + argInfo->Register = false; + argInfo->Ndx = Ofs; + argInfo->Size = Size; + argInfo->Name = Name; + argInfo->TypeDef = TypeDef; + args->Insert(L, (void*)argInfo); + return argInfo; + } + + if (argInfo->Name == "") argInfo->Name = Name; + if (argInfo->TypeDef == "") argInfo->TypeDef = TypeDef; + if (!argInfo->Tag) argInfo->Tag = Tag; + return argInfo; +} +//--------------------------------------------------------------------------- +String __fastcall InfoProcInfo::AddArgsFromDeclaration(char* Decl, int from, int callKind) +{ + bool fColon; + char *p, *pp, *cp, c, sc; + int ss, num; + ARGINFO argInfo; + char _Name[256]; + char _Type[256]; + char _Size[256]; + + p = strchr(Decl, '('); + if (p) + { + p++; pp = p; num = 0; fColon = false; + while (1) + { + c = *pp; + if (c == ')') break; + if (c == ':' && !fColon) + { + *pp = ' '; + num++; + fColon = true; + } + if (c == ';') fColon = false; + pp++; + } + if (num) + { + ss = bpBase; + for (int arg = from;;arg++) + { + _Name[0] = _Type[0] = 0; + sc = ';'; pp = strchr(p, sc); + if (!pp) + { + sc = ')'; + pp = strchr(p, sc); + } + *pp = 0; + //Tag + argInfo.Tag = 0x21; + while (*p == ' ') p++; + sscanf(p, "%s", _Name); + if (!stricmp(_Name, "var")) + { + argInfo.Tag = 0x22; + p += strlen(_Name); + while (*p == ' ') p++; + //Name + sscanf(p, "%s", _Name); + } + + //Insert by ZGL + else if (!stricmp(_Name, "const")) + { + argInfo.Tag = 0x23; + p += strlen(_Name); + while (*p == ' ') p++; + //Name + sscanf(p, "%s", _Name); + } + //////////////// + + else if (!stricmp(_Name, "val")) + { + p += strlen(_Name); + while (*p == ' ') p++; + //Name + sscanf(p, "%s", _Name); + } + p += strlen(_Name); + while (*p == ' ') p++; + //Type + strcpy(_Type, p); + p += strlen(_Type); + while (*p == ' ') p++; + argInfo.Size = 4; + cp = strchr(_Type, ':'); + if (cp) + { + sscanf(cp + 1, "%d", &argInfo.Size); + *cp = 0; + } + if (callKind == 0)//fastcall + { + if (arg < 3 && argInfo.Size == 4) + argInfo.Ndx = arg; + else + { + argInfo.Ndx = ss; + ss += argInfo.Size; + } + } + else + { + argInfo.Ndx = ss; + ss += argInfo.Size; + } + if (_Name[0] == '?' && _Name[1] == 0) + argInfo.Name = ""; + else + argInfo.Name = String(_Name).Trim(); + + if (_Type[0] == '?' && _Type[1] == 0) + argInfo.TypeDef = ""; + else + argInfo.TypeDef = TrimTypeName(String(_Type)); + + AddArg(&argInfo); + *pp = ' '; + p = pp + 1; + if (sc == ')') break; + } + } + } + else + { + p = Decl; + } + p = strchr(p, ':'); + if (p) + { + p++; + pp = strchr(p, ';'); + if (pp) + { + *pp = 0; + strcpy(_Name, p); + *pp = ';'; + } + else + strcpy(_Name, p); + return String(_Name).Trim(); + } + return ""; +} +//--------------------------------------------------------------------------- +PARGINFO __fastcall InfoProcInfo::GetArg(int n) +{ + if (args && n >= 0 && n < args->Count) return (PARGINFO)args->Items[n]; + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall InfoProcInfo::DeleteArg(int n) +{ + if (args && n >= 0 && n < args->Count) args->Delete(n); +} +//--------------------------------------------------------------------------- +void __fastcall InfoProcInfo::DeleteArgs() +{ + if (args) + { + for (int n = 0; n < args->Count; n++) args->Delete(n); + args->Clear(); + } +} +//--------------------------------------------------------------------------- +PLOCALINFO __fastcall InfoProcInfo::AddLocal(int Ofs, int Size, String Name, String TypeDef) +{ + PLOCALINFO locInfo; + + if (!locals) locals = new TList; + if (!locals->Count) + { + locInfo = new LOCALINFO; + locInfo->Ofs = Ofs; + locInfo->Size = Size; + locInfo->Name = Name; + locInfo->TypeDef = TypeDef; + locals->Add((void*)locInfo); + return locInfo; + } + + int F = 0; + locInfo = (PLOCALINFO)locals->Items[F]; + if (-Ofs < -locInfo->Ofs) + { + locInfo = new LOCALINFO; + locInfo->Ofs = Ofs; + locInfo->Size = Size; + locInfo->Name = Name; + locInfo->TypeDef = TypeDef; + locals->Insert(F, (void*)locInfo); + return locInfo; + } + int L = locals->Count - 1; + locInfo = (PLOCALINFO)locals->Items[L]; + if (-Ofs > -locInfo->Ofs) + { + locInfo = new LOCALINFO; + locInfo->Ofs = Ofs; + locInfo->Size = Size; + locInfo->Name = Name; + locInfo->TypeDef = TypeDef; + locals->Add((void*)locInfo); + return locInfo; + } + while (F < L) + { + int M = (F + L)/2; + locInfo = (PLOCALINFO)locals->Items[M]; + if (-Ofs <= -locInfo->Ofs) + L = M; + else + F = M + 1; + } + locInfo = (PLOCALINFO)locals->Items[L]; + if (locInfo->Ofs != Ofs) + { + locInfo = new LOCALINFO; + locInfo->Ofs = Ofs; + locInfo->Size = Size; + locInfo->Name = Name; + locInfo->TypeDef = TypeDef; + locals->Insert(L, (void*)locInfo); + } + else + { + if (Name != "") locInfo->Name = Name; + if (TypeDef != "") locInfo->TypeDef = TypeDef; + } + return locInfo; +} +//--------------------------------------------------------------------------- +PLOCALINFO __fastcall InfoProcInfo::GetLocal(int Ofs) +{ + if (locals) + { + for (int n = 0; n < locals->Count; n++) + { + PLOCALINFO locInfo = (PLOCALINFO)locals->Items[n]; + if (locInfo->Ofs == Ofs) return locInfo; + } + } + return 0; +} +//--------------------------------------------------------------------------- +PLOCALINFO __fastcall InfoProcInfo::GetLocal(String Name) +{ + if (locals) + { + for (int n = 0; n < locals->Count; n++) + { + PLOCALINFO locInfo = (PLOCALINFO)locals->Items[n]; + if (SameText(locInfo->Name, Name)) return locInfo; + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall InfoProcInfo::DeleteLocal(int n) +{ + if (locals && n >= 0 && n < locals->Count) locals->Delete(n); +} +//--------------------------------------------------------------------------- +void __fastcall InfoProcInfo::DeleteLocals() +{ + if (locals) + { + for (int n = 0; n < locals->Count; n++) locals->Delete(n); + locals->Clear(); + } +} +//--------------------------------------------------------------------------- +void __fastcall InfoProcInfo::SetLocalType(int Ofs, String TypeDef) +{ + PLOCALINFO locInfo = GetLocal(Ofs); + if (locInfo) + { + String fname = locInfo->Name; + int pos = fname.Pos("."); + if (pos) + fname = fname.SubString(1, pos - 1); + locInfo->TypeDef = TypeDef; + int size; + if (TypeDef != "" && GetTypeKind(TypeDef, &size) == ikRecord) + { + String recFileName = FMain_11011981->WrkDir + "\\types.idr"; + FILE* recFile = fopen(recFileName.c_str(), "rt"); + if (recFile) + { + while (1) + { + if (!fgets(StringBuf, 1024, recFile)) break; + String str = String(StringBuf); + if (str.Pos(TypeDef + "=") == 1) + { + while (1) + { + if (!fgets(StringBuf, 1024, recFile)) break; + str = String(StringBuf); + if (str.Pos("end;")) break; + if (str.Pos("//")) + { + int ofs = StrGetRecordFieldOffset(str); + String name = StrGetRecordFieldName(str); + String type = StrGetRecordFieldType(str); + if (ofs >= 0) + AddLocal(ofs + Ofs, 1, fname + "." + name, type); + } + } + } + } + fclose(recFile); + } + while (1) + { + //KB + WORD* uses = KnowledgeBase.GetTypeUses(TypeDef.c_str()); + int idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, TypeDef.c_str()); + if (uses) delete[] uses; + + if (idx == -1) break; + + idx = KnowledgeBase.TypeOffsets[idx].NamId; + MTypeInfo tInfo; + if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS, &tInfo)) + { + if (tInfo.FieldsNum) + { + char* p = tInfo.Fields; + for (int k = 0; k < tInfo.FieldsNum; k++) + { + //Scope + p++; + int elofs = *((int*)p); p += 4; + p += 4;//case + //Name + int len = *((WORD*)p); p += 2; + String name = String((char*)p, len); p += len + 1; + //Type + len = *((WORD*)p); p += 2; + String type = TrimTypeName(String((char*)p, len)); p += len + 1; + AddLocal(Ofs + elofs, 1, fname + "." + name, type); + } + break; + } + if (tInfo.Decl != "") + { + TypeDef = tInfo.Decl; + } + } + } + } + } +} +//--------------------------------------------------------------------------- +__fastcall InfoRec::InfoRec(int APos, BYTE AKind) +{ + counter = 0; + kind = AKind; + kbIdx = -1; + name = ""; + type = ""; + picode = 0; + xrefs = 0; + rsInfo = 0; + vmtInfo = 0; + procInfo = 0; + + if (kind == ikResString) + rsInfo = new InfoResStringInfo; + else if (kind == ikVMT) + vmtInfo = new InfoVmtInfo; + else if (kind >= ikRefine && kind <= ikFunc) + procInfo = new InfoProcInfo; + + if (APos >= 0) + { + if (Infos[APos]) + { + //as: if we here - memory leak then! + ++stat_InfosOverride; + } + Infos[APos] = this; + } +} +//--------------------------------------------------------------------------- +__fastcall InfoRec::~InfoRec() +{ + if (picode) delete picode; + + CleanupList(xrefs); + + if (kind == ikResString) + { + delete rsInfo; rsInfo = 0; + } + else if (kind == ikVMT) + { + delete vmtInfo; vmtInfo = 0; + } + else if (kind >= ikRefine && kind <= ikFunc) + { + delete procInfo; procInfo = 0; + } +} +//--------------------------------------------------------------------------- +bool __fastcall InfoRec::HasName() +{ + return (name != ""); +} +//--------------------------------------------------------------------------- +String __fastcall InfoRec::GetName() +{ + return name; +} +//--------------------------------------------------------------------------- +int __fastcall InfoRec::GetNameLength() +{ + return name.Length(); +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::SetName(String AValue) +{ + CrtSection->Enter(); + name = AValue; + if (ExtractClassName(name) != "" && (kind >= ikRefine && kind <= ikFunc) && procInfo) procInfo->flags |= PF_METHOD; + CrtSection->Leave(); +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::ConcatName(String AValue) +{ + name += AValue; +} +//--------------------------------------------------------------------------- +bool __fastcall InfoRec::SameName(String AValue) +{ + return SameText(name, AValue); +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::AddXref(char Type, DWORD Adr, int Offset) +{ + PXrefRec recX; + + if (!xrefs) xrefs = new TList; + if (!xrefs->Count) + { + recX = new XrefRec; + recX->type = Type; + recX->adr = Adr; + recX->offset = Offset; + xrefs->Add((void*)recX); + return; + } + + int F = 0; + recX = (PXrefRec)xrefs->Items[F]; + if (Adr + Offset < recX->adr + recX->offset) + { + recX = new XrefRec; + recX->type = Type; + recX->adr = Adr; + recX->offset = Offset; + xrefs->Insert(F, (void*)recX); + return; + } + int L = xrefs->Count - 1; + recX = (PXrefRec)xrefs->Items[L]; + if (Adr + Offset > recX->adr + recX->offset) + { + recX = new XrefRec; + recX->type = Type; + recX->adr = Adr; + recX->offset = Offset; + xrefs->Add((void*)recX); + return; + } + while (F < L) + { + int M = (F + L)/2; + recX = (PXrefRec)xrefs->Items[M]; + if (Adr + Offset <= recX->adr + recX->offset) + L = M; + else + F = M + 1; + } + recX = (PXrefRec)xrefs->Items[L]; + if (recX->adr + recX->offset != Adr + Offset) + { + recX = new XrefRec; + recX->type = Type; + recX->adr = Adr; + recX->offset = Offset; + xrefs->Insert(L, (void*)recX); + } +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::DeleteXref(DWORD Adr) +{ + for (int n = 0; n < xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)xrefs->Items[n]; + if (Adr == recX->adr + recX->offset) + { + xrefs->Delete(n); + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::ScanUpItemAndAddRef(int fromPos, DWORD itemAdr, char refType, DWORD refAdr) +{ + while (fromPos >= 0) + { + fromPos--; + if (IsFlagSet(cfProcStart, fromPos)) + break; + if (IsFlagSet(cfInstruction, fromPos)) + { + DISINFO _disInfo; + Disasm.Disassemble(Code + fromPos, (__int64)Pos2Adr(fromPos), &_disInfo, 0); + if (_disInfo.Immediate == itemAdr || _disInfo.Offset == itemAdr) + { + AddXref(refType, refAdr, Pos2Adr(fromPos) - refAdr); + break; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::Save(FILE* outs) +//void __fastcall InfoRec::Save(TStream* outs) +{ + int m, xm, num, xnum, len; + + //kbIdx + fwrite(&kbIdx, sizeof(kbIdx), 1, outs);//outs->Write(&kbIdx, sizeof(kbIdx)); + //name + len = name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(name.c_str(), len, 1, outs);//outs->Write(name.c_str(), len); + //type + len = type.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(type.c_str(), len, 1, outs);//outs->Write(type.c_str(), len); + //picode + fwrite(&picode, sizeof(picode), 1, outs);//outs->Write(&picode, sizeof(picode)); + if (picode) + { + //Op + fwrite(&picode->Op, sizeof(picode->Op), 1, outs);//outs->Write(&picode->Op, sizeof(picode->Op)); + //Ofs + if (picode->Op == OP_CALL) + fwrite(&picode->Ofs.Address, sizeof(picode->Ofs.Address), 1, outs);//outs->Write(&picode->Ofs.Address, sizeof(picode->Ofs.Address)); + else + fwrite(&picode->Ofs.Offset, sizeof(picode->Ofs.Offset), 1, outs);//outs->Write(&picode->Ofs.Offset, sizeof(picode->Ofs.Offset)); + //Name + len = picode->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(picode->Name.c_str(), len, 1, outs);//outs->Write(picode->Name.c_str(), len); + } + //xrefs + if (xrefs && xrefs->Count) + num = xrefs->Count; + else + num = 0; + fwrite(&num, sizeof(num), 1, outs);//outs->Write(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + PXrefRec recX = (PXrefRec)xrefs->Items[m]; + //type + fwrite(&recX->type, sizeof(recX->type), 1, outs);//outs->Write(&recX->type, sizeof(recX->type)); + //adr + fwrite(&recX->adr, sizeof(recX->adr), 1, outs);//outs->Write(&recX->adr, sizeof(recX->adr)); + //offset + fwrite(&recX->offset, sizeof(recX->offset), 1, outs);//outs->Write(&recX->offset, sizeof(recX->offset)); + } + if (kind == ikResString) + { + //value + len = rsInfo->value.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(rsInfo->value.c_str(), len, 1, outs);//outs->Write(rsInfo->value.c_str(), len); + } + else if (kind == ikVMT) + { + //interfaces + if (vmtInfo->interfaces && vmtInfo->interfaces->Count) + num = vmtInfo->interfaces->Count; + else + num = 0; + fwrite(&num, sizeof(num), 1, outs);//outs->Write(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + len = vmtInfo->interfaces->Strings[m].Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(vmtInfo->interfaces->Strings[m].c_str(), len, 1, outs);//outs->Write(vmtInfo->interfaces->Strings[m].c_str(), len); + } + //fields + if (vmtInfo->fields && vmtInfo->fields->Count) + num = vmtInfo->fields->Count; + else + num = 0; + fwrite(&num, sizeof(num), 1, outs);//outs->Write(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + PFIELDINFO fInfo = (PFIELDINFO)vmtInfo->fields->Items[m]; + //Scope + fwrite(&fInfo->Scope, sizeof(fInfo->Scope), 1, outs);//outs->Write(&fInfo->Scope, sizeof(fInfo->Scope)); + //Offset + fwrite(&fInfo->Offset, sizeof(fInfo->Offset), 1, outs);//outs->Write(&fInfo->Offset, sizeof(fInfo->Offset)); + //Case + fwrite(&fInfo->Case, sizeof(fInfo->Case), 1, outs);//outs->Write(&fInfo->Case, sizeof(fInfo->Case)); + //Name + len = fInfo->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(fInfo->Name.c_str(), len, 1, outs);//outs->Write(fInfo->Name.c_str(), len); + //Type + len = fInfo->Type.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(fInfo->Type.c_str(), len, 1, outs);//outs->Write(fInfo->Type.c_str(), len); + //xrefs + if (fInfo->xrefs && fInfo->xrefs->Count) + xnum = fInfo->xrefs->Count; + else + xnum = 0; + fwrite(&xnum, sizeof(xnum), 1, outs);//outs->Write(&xnum, sizeof(xnum)); + for (xm = 0; xm < xnum; xm++) + { + PXrefRec recX = (PXrefRec)fInfo->xrefs->Items[xm]; + //type + fwrite(&recX->type, sizeof(recX->type), 1, outs);//outs->Write(&recX->type, sizeof(recX->type)); + //adr + fwrite(&recX->adr, sizeof(recX->adr), 1, outs);//outs->Write(&recX->adr, sizeof(recX->adr)); + //offset + fwrite(&recX->offset, sizeof(recX->offset), 1, outs);//outs->Write(&recX->offset, sizeof(recX->offset)); + } + } + //methods + if (vmtInfo->methods && vmtInfo->methods->Count) + num = vmtInfo->methods->Count; + else + num = 0; + fwrite(&num, sizeof(num), 1, outs);//outs->Write(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + PMethodRec recM = (PMethodRec)vmtInfo->methods->Items[m]; + fwrite(&recM->abstract, sizeof(recM->abstract), 1, outs);//outs->Write(&recM->abstract, sizeof(recM->abstract)); + fwrite(&recM->kind, sizeof(recM->kind), 1, outs);//outs->Write(&recM->kind, sizeof(recM->kind)); + fwrite(&recM->id, sizeof(recM->id), 1, outs);//outs->Write(&recM->id, sizeof(recM->id)); + fwrite(&recM->address, sizeof(recM->address), 1, outs);//outs->Write(&recM->address, sizeof(recM->address)); + len = recM->name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(recM->name.c_str(), len, 1, outs);//outs->Write(recM->name.c_str(), len); + } + } + else if (kind >= ikRefine && kind <= ikFunc) + { + //flags + fwrite(&procInfo->flags, sizeof(procInfo->flags), 1, outs);//outs->Write(&procInfo->flags, sizeof(procInfo->flags)); + //bpBase + fwrite(&procInfo->bpBase, sizeof(procInfo->bpBase), 1, outs);//outs->Write(&procInfo->bpBase, sizeof(procInfo->bpBase)); + //retBytes + fwrite(&procInfo->retBytes, sizeof(procInfo->retBytes), 1, outs);//outs->Write(&procInfo->retBytes, sizeof(procInfo->retBytes)); + //procSize + fwrite(&procInfo->procSize, sizeof(procInfo->procSize), 1, outs);//outs->Write(&procInfo->procSize, sizeof(procInfo->procSize)); + //stackSize + fwrite(&procInfo->stackSize, sizeof(procInfo->stackSize), 1, outs);//outs->Write(&procInfo->stackSize, sizeof(procInfo->stackSize)); + //args + if (procInfo->args && procInfo->args->Count) + num = procInfo->args->Count; + else + num = 0; + fwrite(&num, sizeof(num), 1, outs);//outs->Write(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + PARGINFO argInfo = (PARGINFO)procInfo->args->Items[m]; + //Tag + fwrite(&argInfo->Tag, sizeof(argInfo->Tag), 1, outs);//outs->Write(&argInfo->Tag, sizeof(argInfo->Tag)); + //Register + fwrite(&argInfo->Register, sizeof(argInfo->Register), 1, outs);//outs->Write(&argInfo->Register, sizeof(argInfo->Register)); + //Ndx + fwrite(&argInfo->Ndx, sizeof(argInfo->Ndx), 1, outs);//outs->Write(&argInfo->Ndx, sizeof(argInfo->Ndx)); + //Size + fwrite(&argInfo->Size, sizeof(argInfo->Size), 1, outs);//outs->Write(&argInfo->Size, sizeof(argInfo->Size)); + //Name + len = argInfo->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(argInfo->Name.c_str(), len, 1, outs);//outs->Write(argInfo->Name.c_str(), len); + //TypeDef + len = argInfo->TypeDef.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(argInfo->TypeDef.c_str(), len, 1, outs);//outs->Write(argInfo->TypeDef.c_str(), len); + } + //locals + if (procInfo->locals && procInfo->locals->Count) + num = procInfo->locals->Count; + else + num = 0; + fwrite(&num, sizeof(num), 1, outs);//outs->Write(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + PLOCALINFO locInfo = (PLOCALINFO)procInfo->locals->Items[m]; + //Ofs + fwrite(&locInfo->Ofs, sizeof(locInfo->Ofs), 1, outs);//outs->Write(&locInfo->Ofs, sizeof(locInfo->Ofs)); + //Size + fwrite(&locInfo->Size, sizeof(locInfo->Size), 1, outs);//outs->Write(&locInfo->Size, sizeof(locInfo->Size)); + //Name + len = locInfo->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(locInfo->Name.c_str(), len, 1, outs);//outs->Write(locInfo->Name.c_str(), len); + //TypeDef + len = locInfo->TypeDef.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outs);//outs->Write(&len, sizeof(len)); + fwrite(locInfo->TypeDef.c_str(), len, 1, outs);//outs->Write(locInfo->TypeDef.c_str(), len); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall InfoRec::Load(FILE* ins, char* buf)//void __fastcall InfoRec::Load(TStream* ins, char* buf) +{ + int m, xm, num, xnum, len, xrefAdr, pxrefAdr; + XrefRec recX1; + + //kbIdx + fread(&kbIdx, sizeof(kbIdx), 1, ins);//ins->Read(&kbIdx, sizeof(kbIdx)); + //name + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + name = String(buf, len); + //type + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + type = String(buf, len); + //picode + fread(&picode, sizeof(picode), 1, ins);//ins->Read(&picode, sizeof(picode)); + if (picode) + { + picode = new PICODE; + //Op + fread(&picode->Op, sizeof(picode->Op), 1, ins);//ins->Read(&picode->Op, sizeof(picode->Op)); + //Ofs + if (picode->Op == OP_CALL) + fread(&picode->Ofs.Address, sizeof(picode->Ofs.Address), 1, ins);//ins->Read(&picode->Ofs.Address, sizeof(picode->Ofs.Address)); + else + fread(&picode->Ofs.Offset, sizeof(picode->Ofs.Offset), 1, ins);//ins->Read(&picode->Ofs.Offset, sizeof(picode->Ofs.Offset)); + //Name + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + picode->Name = String(buf, len); + } + //xrefs + fread(&num, sizeof(num), 1, ins);//ins->Read(&num, sizeof(num)); + if (num) xrefs = new TList; + pxrefAdr = 0; + for (m = 0; m < num; m++) + { + //type + fread(&recX1.type, sizeof(recX1.type), 1, ins);//ins->Read(&recX1.type, sizeof(recX1.type)); + //adr + fread(&recX1.adr, sizeof(recX1.adr), 1, ins);//ins->Read(&recX1.adr, sizeof(recX1.adr)); + //offset + fread(&recX1.offset, sizeof(recX1.offset), 1, ins);//ins->Read(&recX1.offset, sizeof(recX1.offset)); + xrefAdr = recX1.adr + recX1.offset; + if (!pxrefAdr || pxrefAdr != xrefAdr) //clear duplicates + { + PXrefRec recX = new XrefRec; + recX->type = recX1.type; + recX->adr = recX1.adr; + recX->offset = recX1.offset; + xrefs->Add((void*)recX); + pxrefAdr = xrefAdr; + } + } + if (kind == ikResString) + { + //value + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + rsInfo->value = String(buf, len); + } + else if (kind == ikVMT) + { + //interfaces + fread(&num, sizeof(num), 1, ins);//ins->Read(&num, sizeof(num)); + if (num) vmtInfo->interfaces = new TStringList; + for (m = 0; m < num; m++) + { + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + vmtInfo->interfaces->Add(String(buf, len)); + } + //fields + fread(&num, sizeof(num), 1, ins);//ins->Read(&num, sizeof(num)); + if (num) vmtInfo->fields = new TList; + for (m = 0; m < num; m++) + { + PFIELDINFO fInfo = new FIELDINFO; + //Scope + fread(&fInfo->Scope, sizeof(fInfo->Scope), 1, ins);//ins->Read(&fInfo->Scope, sizeof(fInfo->Scope)); + //Offset + fread(&fInfo->Offset, sizeof(fInfo->Offset), 1, ins);//ins->Read(&fInfo->Offset, sizeof(fInfo->Offset)); + //Case + fread(&fInfo->Case, sizeof(fInfo->Case), 1, ins);//ins->Read(&fInfo->Case, sizeof(fInfo->Case)); + //Name + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + fInfo->Name = String(buf, len); + //Type + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + fInfo->Type = String(buf, len); + //xrefs + fread(&xnum, sizeof(xnum), 1, ins);//ins->Read(&xnum, sizeof(xnum)); + if (xnum) + fInfo->xrefs = new TList; + else + fInfo->xrefs = 0; + for (xm = 0; xm < xnum; xm++) + { + PXrefRec recX = new XrefRec; + //type + fread(&recX->type, sizeof(recX->type), 1, ins);//ins->Read(&recX->type, sizeof(recX->type)); + //adr + fread(&recX->adr, sizeof(recX->adr), 1, ins);//ins->Read(&recX->adr, sizeof(recX->adr)); + //offset + fread(&recX->offset, sizeof(recX->offset), 1, ins);//ins->Read(&recX->offset, sizeof(recX->offset)); + fInfo->xrefs->Add((void*)recX); + } + vmtInfo->fields->Add((void*)fInfo); + } + //methods + fread(&num, sizeof(num), 1, ins);//ins->Read(&num, sizeof(num)); + if (num) vmtInfo->methods = new TList; + for (m = 0; m < num; m++) + { + PMethodRec recM = new MethodRec; + fread(&recM->abstract, sizeof(recM->abstract), 1, ins);//ins->Read(&recM->abstract, sizeof(recM->abstract)); + fread(&recM->kind, sizeof(recM->kind), 1, ins);//ins->Read(&recM->kind, sizeof(recM->kind)); + fread(&recM->id, sizeof(recM->id), 1, ins);//ins->Read(&recM->id, sizeof(recM->id)); + fread(&recM->address, sizeof(recM->address), 1, ins);//ins->Read(&recM->address, sizeof(recM->address)); + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + recM->name = String(buf, len); + vmtInfo->methods->Add((void*)recM); + } + } + else if (kind >= ikRefine && kind <= ikFunc) + { + //flags + fread(&procInfo->flags, sizeof(procInfo->flags), 1, ins);//ins->Read(&procInfo->flags, sizeof(procInfo->flags)); + //bpBase + fread(&procInfo->bpBase, sizeof(procInfo->bpBase), 1, ins);//ins->Read(&procInfo->bpBase, sizeof(procInfo->bpBase)); + //retBytes + fread(&procInfo->retBytes, sizeof(procInfo->retBytes), 1, ins);//ins->Read(&procInfo->retBytes, sizeof(procInfo->retBytes)); + //procSize + fread(&procInfo->procSize, sizeof(procInfo->procSize), 1, ins);//ins->Read(&procInfo->procSize, sizeof(procInfo->procSize)); + //stackSize + fread(&procInfo->stackSize, sizeof(procInfo->stackSize), 1, ins);//ins->Read(&procInfo->stackSize, sizeof(procInfo->stackSize)); + //args + fread(&num, sizeof(num), 1, ins);//ins->Read(&num, sizeof(num)); + if (num) procInfo->args = new TList; + for (m = 0; m < num; m++) + { + PARGINFO argInfo = new ARGINFO; + //Tag + fread(&argInfo->Tag, sizeof(argInfo->Tag), 1, ins);//ins->Read(&argInfo->Tag, sizeof(argInfo->Tag)); + //Register + fread(&argInfo->Register, sizeof(argInfo->Register), 1, ins);//ins->Read(&argInfo->Register, sizeof(argInfo->Register)); + //Ndx + fread(&argInfo->Ndx, sizeof(argInfo->Ndx), 1, ins);//ins->Read(&argInfo->Ndx, sizeof(argInfo->Ndx)); + //Size + fread(&argInfo->Size, sizeof(argInfo->Size), 1, ins);//ins->Read(&argInfo->Size, sizeof(argInfo->Size)); + //Name + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + argInfo->Name = String(buf, len); + //TypeDef + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + argInfo->TypeDef = TrimTypeName(String(buf, len)); + procInfo->args->Add((void*)argInfo); + } + //locals + fread(&num, sizeof(num), 1, ins);//ins->Read(&num, sizeof(num)); + if (num) procInfo->locals = new TList; + for (m = 0; m < num; m++) + { + PLOCALINFO locInfo = new LOCALINFO; + //Ofs + fread(&locInfo->Ofs, sizeof(locInfo->Ofs), 1, ins);//ins->Read(&locInfo->Ofs, sizeof(locInfo->Ofs)); + //Size + fread(&locInfo->Size, sizeof(locInfo->Size), 1, ins);//ins->Read(&locInfo->Size, sizeof(locInfo->Size)); + //Name + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + locInfo->Name = String(buf, len); + //TypeDef + fread(&len, sizeof(len), 1, ins);//ins->Read(&len, sizeof(len)); + fread(buf, len, 1, ins);//ins->Read(buf, len); + locInfo->TypeDef = TrimTypeName(String(buf, len)); + procInfo->locals->Add((void*)locInfo); + } + } +} +//--------------------------------------------------------------------------- +/* +void __fastcall InfoRec::Skip(TStream* ins, char* buf, BYTE asKind) +{ + DWORD dummy; + int m, xm, len, num, xnum; + PICODE picode; + XrefRec recX; + FIELDINFO fInfo; + MethodRec recM; + ARGINFO argInfo; + LOCALINFO locInfo; + + //kbIdx + ins->Read(&dummy, sizeof(kbIdx)); + //name + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + //type + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + //picode + ins->Read(&dummy, sizeof(dummy)); + if (dummy) + { + //Op + ins->Read(&picode.Op, sizeof(picode.Op)); + //Ofs + if (dummy == OP_CALL) + ins->Read(&picode.Ofs.Address, sizeof(picode.Ofs.Address)); + else + ins->Read(&picode.Ofs.Offset, sizeof(picode.Ofs.Offset)); + //Name + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + } + //xrefs + ins->Read(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + //type + ins->Read(&recX.type, sizeof(recX.type)); + //adr + ins->Read(&recX.adr, sizeof(recX.adr)); + //offset + ins->Read(&recX.offset, sizeof(recX.offset)); + } + if (asKind == ikResString) + { + //value + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + } + else if (asKind == ikVMT) + { + //interfaces + ins->Read(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + } + //fields + ins->Read(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + //Scope + ins->Read(&fInfo.Scope, sizeof(fInfo.Scope)); + //Offset + ins->Read(&fInfo.Offset, sizeof(fInfo.Offset)); + //Case + ins->Read(&fInfo.Case, sizeof(fInfo.Case)); + //Name + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + //Type + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + //xrefs + ins->Read(&xnum, sizeof(xnum)); + for (xm = 0; xm < xnum; xm++) + { + //type + ins->Read(&recX.type, sizeof(recX.type)); + //adr + ins->Read(&recX.adr, sizeof(recX.adr)); + //offset + ins->Read(&recX.offset, sizeof(recX.offset)); + } + } + //methods + ins->Read(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + ins->Read(&recM.abstract, sizeof(recM.abstract)); + ins->Read(&recM.kind, sizeof(recM.kind)); + ins->Read(&recM.id, sizeof(recM.id)); + ins->Read(&recM.address, sizeof(recM.address)); + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + } + } + else if (asKind >= ikRefine && asKind <= ikFunc) + { + //flags + ins->Read(&dummy, sizeof(info.procInfo->flags)); + //bpBase + ins->Read(&dummy, sizeof(info.procInfo->bpBase)); + //retBytes + ins->Read(&dummy, sizeof(info.procInfo->retBytes)); + //procSize + ins->Read(&dummy, sizeof(info.procInfo->procSize)); + //stackSize + ins->Read(&dummy, sizeof(info.procInfo->stackSize)); + //args + ins->Read(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + //Tag + ins->Read(&argInfo.Tag, sizeof(argInfo.Tag)); + //Register + ins->Read(&argInfo.Register, sizeof(argInfo.Register)); + //Ndx + ins->Read(&argInfo.Ndx, sizeof(argInfo.Ndx)); + //Size + ins->Read(&argInfo.Size, sizeof(argInfo.Size)); + //Name + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + //TypeDef + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + } + //locals + ins->Read(&num, sizeof(num)); + for (m = 0; m < num; m++) + { + //Ofs + ins->Read(&locInfo.Ofs, sizeof(locInfo.Ofs)); + //Size + ins->Read(&locInfo.Size, sizeof(locInfo.Size)); + //Name + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + //TypeDef + ins->Read(&len, sizeof(len)); + ins->Read(buf, len); + } + } +} +*/ +//--------------------------------------------------------------------------- +String __fastcall InfoRec::MakePrototype(int adr, bool showKind, bool showTail, bool multiline, bool fullName, bool allArgs) +{ + BYTE callKind; + int n, num, argsNum, firstArg; + PARGINFO argInfo; + String result = ""; + + if (showKind) + { + if (kind == ikConstructor) + result += "constructor"; + else if (kind == ikDestructor) + result += "destructor"; + else if (kind == ikFunc) + result += "function"; + else if (kind == ikProc) + result += "procedure"; + + if (result != "") result += " "; + } + + if (name != "") + { + if (!fullName) + result += ExtractProcName(name); + else + result += name; + } + else + result += GetDefaultProcName(adr); + + num = argsNum = (procInfo->args) ? procInfo->args->Count : 0; firstArg = 0; + + if (num && !allArgs) + { + if (kind == ikConstructor || kind == ikDestructor) + { + firstArg = 2; + num -= 2; + } + else if (procInfo->flags & PF_ALLMETHODS) + { + firstArg = 1; + num--; + } + } + if (num) + { + result += "("; + if (multiline) result += "\r\n"; + + for (n = firstArg; n < argsNum; n++) + { + if (n != firstArg) + { + result += ";"; + if (multiline) + result += "\r\n"; + else + result += " "; + } + + argInfo = (PARGINFO)procInfo->args->Items[n]; + if (argInfo->Tag == 0x22) result += "var "; + + else if (argInfo->Tag == 0x23) result += "const "; //Add by ZGL + + if (argInfo->Name != "") + result += argInfo->Name; + else + result += "?"; + result += ":"; + if (argInfo->TypeDef != "" && argInfo->TypeDef[1] >= 'A' && argInfo->TypeDef[1] <= 'z') + result += argInfo->TypeDef; + else + result += "?"; + } + + if (multiline) result += "\r\n"; + result += ")"; + } + + if (kind == ikFunc) + { + result += ":"; + if (type != "") + result += TrimTypeName(type); + else + result += "?"; + } + result += ";"; + callKind = procInfo->flags & 7; + switch (callKind) + { + case 1: + result += " cdecl;"; + break; + case 2: + result += " pascal;"; + break; + case 3: + result += " stdcall;"; + break; + case 4: + result += " safecall;"; + break; + } + String argres = ""; + //fastcall + if (!callKind)//(!IsFlagSet(cfImport, Adr2Pos(Adr))) + { + for (n = 0; n < argsNum; n++) + { + argInfo = (PARGINFO)procInfo->args->Items[n]; + if (argInfo->Ndx == 0) + argres += "A"; + else if (argInfo->Ndx == 1) + argres += "D"; + else if (argInfo->Ndx == 2) + argres += "C"; + } + } + if (showTail) + { + if (argres != "") result += " in" + argres; + //output registers + //if (info.procInfo->flags & PF_OUTEAX) result += " out"; + + if (procInfo->retBytes) + result += " RET" + Val2Str0(procInfo->retBytes); + + if (procInfo->flags & PF_ARGSIZEG) result += "+"; + if (procInfo->flags & PF_ARGSIZEL) result += "-"; + } + return result; +} +//--------------------------------------------------------------------------- +String __fastcall InfoRec::MakeDelphiPrototype(int Adr, PMethodRec recM) +{ + bool abstract = false; + BYTE callKind; + int n, num, argsNum, firstArg, len = 0; + PARGINFO argInfo; + + if (kind == ikConstructor) + len = sprintf(StringBuf, "constructor"); + else if (kind == ikDestructor) + len = sprintf(StringBuf, "destructor"); + else if (kind == ikFunc) + len = sprintf(StringBuf, "function"); + else if (kind == ikProc) + len = sprintf(StringBuf, "procedure"); + + if (len > 0) len += sprintf(StringBuf + len, " "); + + if (SameText(name, "@AbstractError")) abstract = true; + + if (name != "") + { + if (!abstract) + len += sprintf(StringBuf + len, "%s", ExtractProcName(name).c_str()); + else if (recM->name != "") + len += sprintf(StringBuf + len, "%s", ExtractProcName(recM->name).c_str()); + else + len += sprintf(StringBuf + len, "v%X", recM->id); + } + else + len += sprintf(StringBuf + len, "v%X", recM->id); + + num = argsNum = (procInfo->args) ? procInfo->args->Count : 0; firstArg = 0; + + if (num) + { + if (procInfo->flags & PF_ALLMETHODS) + { + firstArg = 1; + num--; + if (kind == ikConstructor || kind == ikDestructor) + { + firstArg++; + num--; + } + } + if (num) + { + len += sprintf(StringBuf + len, "("); + + callKind = procInfo->flags & 7; + for (n = firstArg; n < argsNum; n++) + { + if (n != firstArg) len += sprintf(StringBuf + len, "; "); + + argInfo = (PARGINFO)procInfo->args->Items[n]; + if (argInfo->Tag == 0x22) len += sprintf(StringBuf + len, "var "); + + else if (argInfo->Tag == 0x23) len += sprintf(StringBuf + len, "const "); //Add by ZGL + + if (argInfo->Name != "") + len += sprintf(StringBuf + len, "%s", argInfo->Name.c_str()); + else + len += sprintf(StringBuf + len, "?"); + len += sprintf(StringBuf + len, ":"); + if (argInfo->TypeDef != "") + len += sprintf(StringBuf + len, "%s", argInfo->TypeDef.c_str()); + else + len += sprintf(StringBuf + len, "?"); + } + len += sprintf(StringBuf + len, ")"); + } + } + + if (kind == ikFunc) + { + len += sprintf(StringBuf + len, ":"); + if (type != "") + len += sprintf(StringBuf + len, "%s", TrimTypeName(type).c_str()); + else + len += sprintf(StringBuf + len, "?"); + } + len += sprintf(StringBuf + len, "; virtual;"); + + if (abstract) + len += sprintf(StringBuf + len, " abstract;"); + else + { + switch (callKind) + { + case 1: + len += sprintf(StringBuf + len, " cdecl;"); + break; + case 2: + len += sprintf(StringBuf + len, " pascal;"); + break; + case 3: + len += sprintf(StringBuf + len, " stdcall;"); + break; + case 4: + len += sprintf(StringBuf + len, " safecall;"); + break; + } + } + return String(StringBuf, len); +} +//--------------------------------------------------------------------------- +String __fastcall InfoRec::MakeMultilinePrototype(int Adr, int* ArgsBytes, String MethodType) +{ + BYTE callKind; + int n, num, argsNum, firstArg, argsBytes = 0; + PARGINFO argInfo; + String result; + + if (name != "") + result = name; + else + result = GetDefaultProcName(Adr); + + num = argsNum = (procInfo->args) ? procInfo->args->Count : 0; + firstArg = 0; + + if (kind == ikConstructor || kind == ikDestructor) + { + firstArg = 2; + num -= 2; + } + else if (procInfo->flags & PF_ALLMETHODS) + { + if (!num) + { + argInfo = new ARGINFO; + argInfo->Tag = 0x21; + argInfo->Ndx = 0; + argInfo->Size = 4; + argInfo->Name = "Self"; + argInfo->TypeDef = MethodType; + procInfo->AddArg(argInfo); + } + else + { + if (MethodType != "") + { + argInfo = (PARGINFO)procInfo->args->Items[0]; + argInfo->Name = "Self"; + argInfo->TypeDef = MethodType; + procInfo->args->Items[0] = argInfo; + } + num--; + } + firstArg = 1; + } + + if (num > 0) result += "(\r\n"; + callKind = procInfo->flags & 7; + for (n = firstArg; n < argsNum; n++) + { + if (n != firstArg) result += ";\r\n"; + + argInfo = (PARGINFO)procInfo->args->Items[n]; + //var + if (argInfo->Tag == 0x22) result += "var "; + + else if (argInfo->Tag == 0x23) result += "const "; //Add by ZGL + + //name + if (argInfo->Name != "") + result += argInfo->Name; + else + result += "?"; + //type + result += ":"; + if (argInfo->TypeDef != "") + result += argInfo->TypeDef; + else + result += "?"; + //size + if (argInfo->Size > 4) result += ":" + String(argInfo->Size); + + if (argInfo->Ndx > 2) argsBytes += argInfo->Size; + } + if (num > 0) result += "\r\n)"; + + if (kind == ikFunc) + { + result += ":"; + if (type != "") + result += TrimTypeName(type); + else + result += "?"; + } + result += ";"; + *ArgsBytes = argsBytes; + return result; +} +//--------------------------------------------------------------------------- +String __fastcall InfoRec::MakeCppPrototype(int Adr, String FType) +{ + int n, argsNum, typeKind, size; + PARGINFO argInfo; + String argType, result = ""; + + if (kind == ikFunc) + { + if (type != "") + { + result = SanitizeName(TrimTypeName(type)); + typeKind = GetTypeKind(result, &size); + if (typeKind == ikRecord || typeKind == ikVMT) + result = "struct " + result + "*"; + } + else + result = "DWORD"; + } + else + result = "void"; + + result += " __usercall (*"; + if (FType != "") + result += "P" + FType; + result += ")"; + + if (kind == ikFunc) + result += "@"; + result += "("; + + argsNum = (procInfo->args) ? procInfo->args->Count : 0; + for (n = 0; n < argsNum; n++) + { + if (n) result += ", "; + argInfo = (PARGINFO)procInfo->args->Items[n]; + argType = argInfo->TypeDef; + if (argType != "" && argType != "?") + { + typeKind = GetTypeKind(argType, &size); + if (typeKind == ikRecord || typeKind == ikVMT) + result += "struct "; + result += SanitizeName(argType); + if (typeKind == ikVMT) + result += "*"; + } + else + { + result += "DWORD"; + } + if (argInfo->Tag == 0x22) result += "*"; + if (n == 0) + result += "@"; + else if (n == 1) + result += "@"; + else if (n == 2) + result += "@"; + } + result += ")"; + return result; +} +//--------------------------------------------------------------------------- +String __fastcall InfoRec::MakeMapName(int Adr) +{ + String result; + if (name != "") + result = name; + else + result = GetDefaultProcName(Adr); + + return result; +} +//--------------------------------------------------------------------------- +bool __fastcall InfoRec::MakeArgsManually() +{ + String _sname; + + //if (info.procInfo->flags & PF_KBPROTO) return true; + //Some procedures not begin with '@' + //function QueryInterface(Self:Pointer; IID:TGUID; var Obj:Pointer); + if (name.Pos(".QueryInterface")) + { + kind = ikFunc; + type = "HRESULT"; + procInfo->flags &= 0xFFFFFFF8; + procInfo->flags |= 3;//stdcall + procInfo->AddArg(0x21, 8, 4, "Self", ""); + procInfo->AddArg(0x23, 12, 4, "IID", "TGUID"); //Midify by ZGL + procInfo->AddArg(0x22, 16, 4, "Obj", "Pointer"); + return true; + } + //function _AddRef(Self:Pointer):Integer; + //function _Release(Self:Pointer):Integer; + if (name.Pos("._AddRef") || name.Pos("._Release")) + { + kind = ikFunc; + type = "Integer"; + procInfo->flags &= 0xFFFFFFF8; + procInfo->flags |= 3;//stdcall + procInfo->AddArg(0x21, 8, 4, "Self", ""); + return true; + } + //procedure DynArrayClear(var arr:Pointer; typeInfo:PDynArrayTypeInfo); + if (SameText(name, "DynArrayClear")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "arr", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "typeInfo", "PDynArrayTypeInfo"); + return true; + } + //procedure DynArraySetLength(var arr:Pointer; typeInfo:PDynArrayTypeInfo; dimCnt:Longint; lenVec:PLongint); + if (SameText(name, "DynArraySetLength")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "arr", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "typeInfo", "PDynArrayTypeInfo"); + procInfo->AddArg(0x21, 2, 4, "dimCnt", "Longint"); + procInfo->AddArg(0x21, 8, 4, "lenVec", "PLongint"); + return true; + } + + if (name[1] != '@') return false; + + //Strings + if (name[2] == 'L') + _sname = "AnsiString"; + else if (name[2] == 'W') + _sname = "WideString"; + else if (name[2] == 'U') + _sname = "UnicodeString"; + else + _sname = "?"; + + if (_sname != "?") + { + //@LStrClr, @WStrClr, @UStrClr + if (SameText(&name[3], "StrClr")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "S", _sname); + return true; + } + //@LStrArrayClr, @WStrArrayClr, @UStrArrayClr + if (SameText(&name[3], "StrArrayClr")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "StrArray", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "Count", "Integer"); + return true; + } + //@LStrAsg, @WStrAsg, @UStrAsg + if (SameText(&name[3], "StrAsg")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", _sname); + return true; + } + //@LStrLAsg, @WStrLAsg, @UStrLAsg + if (SameText(&name[3], "StrLAsg")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x23, 1, 4, "Source", _sname); //Modify by ZGL + return true; + } + //@LStrFromPCharLen, @WStrFromPCharLen, @UStrFromPCharLen + if (SameText(&name[3], "StrFromPCharLen")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "PAnsiChar"); + procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); + return true; + } + //@LStrFromPWCharLen, @WStrFromPWCharLen, @UStrFromPWCharLen + if (SameText(&name[3], "StrFromPWCharLen")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "PWideChar"); + procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); + return true; + } + //@LStrFromChar, @WStrFromChar, @UStrFromChar + if (SameText(&name[3], "StrFromChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "AnsiChar"); + return true; + } + //@LStrFromWChar, @WStrFromWChar, @UStrFromWChar + if (SameText(&name[3], "StrFromWChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "WideChar"); + return true; + } + //@LStrFromPChar, @WStrFromPChar, @UStrFromPChar + if (SameText(&name[3], "StrFromPChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "PAnsiChar"); + return true; + } + //@LStrFromPWChar, @WStrFromPWChar, @UStrFromPWChar + if (SameText(&name[3], "StrFromPWChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "PWideChar"); + return true; + } + //@LStrFromString, @WStrFromString, @UStrFromString + if (SameText(&name[3], "StrFromString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x23, 1, 4, "Source", "ShortString"); //Modify by ZGL + return true; + } + //@LStrFromArray, @WStrFromArray, @UStrFromArray + if (SameText(&name[3], "StrFromArray")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "PAnsiChar"); + procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); + return true; + } + //@LStrFromWArray, @WStrFromWArray, @UStrFromWArray + if (SameText(&name[3], "StrFromWArray")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", "PWideChar"); + procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); + return 1; + } + //@LStrFromWStr, @UStrFromWStr + if (SameText(&name[3], "StrFromWStr")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x23, 1, 4, "Source", "WideString"); //Modify by ZGL + return true; + } + //@LStrToString, @WStrToString, @UStrToString + if (SameText(&name[3], "StrToString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", "ShortString"); + procInfo->AddArg(0x23, 1, 4, "Source", _sname); //Modify by ZGL + procInfo->AddArg(0x21, 2, 4, "MaxLen", "Integer"); + return true; + } + //@LStrLen, @WStrLen, @UStrLen + if (SameText(&name[3], "StrLen")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x21, 0, 4, "S", _sname); + return true; + } + //@LStrCat, @WStrCat, @UStrCat + if (SameText(&name[3], "StrCat")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", _sname); + return true; + } + //@LStrCat3, @WStrCat3, @UStrCat3 + if (SameText(&name[3], "StrCat3")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source1", _sname); + procInfo->AddArg(0x21, 2, 4, "Source2", _sname); + return true; + } + //@LStrCatN, @WStrCatN, @UStrCatN + if (SameText(&name[3], "StrCatN")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "ArgCnt", "Integer"); + return true; + } + //@LStrCmp, @WStrCmp, @UStrCmp + if (SameText(&name[3], "StrCmp")) //return Flags + { + kind = ikFunc; + procInfo->AddArg(0x21, 0, 4, "Left", _sname); + procInfo->AddArg(0x21, 1, 4, "Right", _sname); + return true; + } + //@LStrAddRef, @WStrAddRef, @UStrAddRef + if (SameText(&name[3], "StrAddRef")) + { + kind = ikFunc; + type = "Pointer"; + procInfo->AddArg(0x22, 0, 4, "S", _sname); + return true; + } + //@LStrToPChar, @WStrToPChar, @UStrToPChar + if (SameText(&name[3], "StrToPChar")) + { + kind = ikFunc; + type = "PChar"; + procInfo->AddArg(0x21, 0, 4, "S", _sname); + return true; + } + //@LStrCopy, @WStrCopy, @UStrCopy + if (SameText(&name[3], "StrCopy")) + { + kind = ikFunc; + type = _sname; + procInfo->AddArg(0x23, 0, 4, "S", _sname); //Modify by ZGL + procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); + procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); + return true; + } + //@LStrDelete, @WStrDelete, @UStrDelete + if (SameText(&name[3], "StrDelete")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "S", _sname); + procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); + procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); + return true; + } + //@LStrInsert, @WStrInsert, @UStrInsert + if (SameText(&name[3], "StrInsert")) + { + kind = ikProc; + procInfo->AddArg(0x23, 0, 4, "Source", _sname); //Modify by ZGL + procInfo->AddArg(0x22, 1, 4, "S", _sname); + procInfo->AddArg(0x21, 2, 4, "Index", "Integer"); + return true; + } + //@LStrPos, @WStrPos, @UStrPos + if (SameText(&name[3], "StrPos")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x23, 0, 4, "Substr", _sname); //Modify by ZGL + procInfo->AddArg(0x23, 1, 4, "S", _sname); //Modify by ZGL + return true; + } + //@LStrSetLength, @WStrSetLength, @UStrSetLength + if (SameText(&name[3], "StrSetLength")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "S", _sname); + procInfo->AddArg(0x21, 1, 4, "NewLen", "Integer"); + return true; + } + //@LStrOfChar, @WStrOfChar, @UStrOfChar + if (SameText(&name[3], "StrOfChar")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 1, "C", "Char"); + procInfo->AddArg(0x21, 1, 4, "Count", "Integer"); + procInfo->AddArg(0x22, 2, 4, "Result", _sname); + return 1; + } + //@WStrToPWChar, @UStrToPWChar + if (SameText(&name[3], "StrToPWChar")) + { + kind = ikFunc; + type = "PWideChar"; + procInfo->AddArg(0x21, 0, 4, "S", _sname); + return true; + } + //@WStrFromLStr, @UStrFromLStr + if (SameText(&name[3], "StrFromLStr")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", _sname); + procInfo->AddArg(0x23, 1, 4, "Source", "AnsiString"); //Modify by ZGL + return true; + } + //@WStrOfWChar + if (SameText(&name[3], "StrOfWChar")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "C", "WideChar"); + procInfo->AddArg(0x21, 1, 4, "Count", "Integer"); + procInfo->AddArg(0x22, 2, 4, "Result", _sname); + return true; + } + //@UStrEqual + if (SameText(&name[3], "StrEqual")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Left", _sname); + procInfo->AddArg(0x21, 1, 4, "Right", _sname); + return true; + } + } + //ShortStrings-------------------------------------------------------------- + _sname = "ShortString"; + //@Copy + if (SameText(name, "@Copy")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "S", _sname); + procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); + procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); + procInfo->AddArg(0x21, 8, 4, "Result", _sname); + return true; + } + //@Delete + if (SameText(name, "@Delete")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "S", _sname); + procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); + procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); + return true; + } + //@Insert + if (SameText(name, "@Insert")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Source", _sname); + procInfo->AddArg(0x22, 1, 4, "Dest", "ShortString"); + procInfo->AddArg(0x21, 2, 4, "Index", "Integer"); + return true; + } + //@Pos + if (SameText(name, "@Pos")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x21, 0, 4, "Substr", _sname); + procInfo->AddArg(0x21, 1, 4, "S", _sname); + return true; + } + _sname = "PShortString"; + //@SetLength + if (SameText(name, "@SetLength")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "S", _sname); + procInfo->AddArg(0x21, 1, 4, "NewLength", "Byte"); + return true; + } + //@SetString + if (SameText(name, "@SetString")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "S", _sname); + procInfo->AddArg(0x21, 1, 4, "Buffer", "PChar"); + procInfo->AddArg(0x21, 2, 4, "Length", "Byte"); + return true; + } + //@PStrCat + if (SameText(name, "@PStrCat")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", _sname); + return true; + } + //@PStrNCat + if (SameText(name, "@PStrNCat")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", _sname); + procInfo->AddArg(0x21, 2, 4, "MaxLen", "Byte"); + return true; + } + //@PStrCpy + if (SameText(name, "@PStrCpy")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", _sname); + return true; + } + //@PStrNCpy + if (SameText(name, "@PStrNCpy")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Dest", _sname); + procInfo->AddArg(0x21, 1, 4, "Source", _sname); + procInfo->AddArg(0x21, 2, 4, "MaxLen", "Byte"); + return true; + } + //@AStrCmp + if (SameText(name, "@AStrCmp")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "S1", _sname); + procInfo->AddArg(0x21, 1, 4, "S2", _sname); + procInfo->AddArg(0x21, 2, 4, "Bytes", "Integer"); + return true; + } + //@PStrCmp + if (SameText(name, "@PStrCmp")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "S1", _sname); + procInfo->AddArg(0x21, 1, 4, "S2", _sname); + return true; + } + //@Str0Long + if (SameText(name, "@Str0Long")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Val", "Longint"); + procInfo->AddArg(0x21, 1, 4, "S", _sname); + return true; + } + //@StrLong + if (SameText(name, "@StrLong")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Val", "Integer"); + procInfo->AddArg(0x21, 1, 4, "Width", "Integer"); + procInfo->AddArg(0x21, 2, 4, "S", _sname); + return true; + } + //Files--------------------------------------------------------------------- + //@Append( + if (SameText(name, "@Append")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@Assign + if (SameText(name, "@Assign")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "S", "String"); + return true; + } + //@BlockRead + if (SameText(name, "@BlockRead")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "buffer", "Pointer"); + procInfo->AddArg(0x21, 2, 4, "recCnt", "Longint"); + procInfo->AddArg(0x22, 8, 4, "recsRead", "Longint"); + return true; + } + //@BlockWrite + if (SameText(name, "@BlockWrite")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "buffer", "Pointer"); + procInfo->AddArg(0x21, 2, 4, "recCnt", "Longint"); + procInfo->AddArg(0x22, 8, 4, "recsWritten", "Longint"); + return true; + } + //@Close + if (SameText(name, "@Close")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@EofFile + if (SameText(name, "@EofFile")) + { + kind = ikFunc; + type = "Boolean"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@EofText + if (SameText(name, "@EofText")) + { + kind = ikFunc; + type = "Boolean"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@Eoln + if (SameText(name, "@Eoln")) + { + kind = ikFunc; + type = "Boolean"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@Erase + if (SameText(name, "@Erase")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@FilePos + if (SameText(name, "@FilePos")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@FileSize + if (SameText(name, "@FileSize")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@Flush + if (SameText(name, "@Flush")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@ReadRec + if (SameText(name, "@ReadRec")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "Buffer", "Pointer"); + return true; + } + //@ReadChar + if (SameText(name, "@ReadChar")) + { + kind = ikFunc; + type = "Char"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@ReadLong + if (SameText(name, "@ReadLong")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@ReadString + if (SameText(name, "@ReadString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PShortString"); + procInfo->AddArg(0x21, 2, 4, "MaxLen", "Longint"); + return true; + } + //@ReadCString + if (SameText(name, "@ReadCString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PAnsiChar"); + procInfo->AddArg(0x21, 2, 4, "MaxLen", "Longint"); + return true; + } + //@ReadLString + if (SameText(name, "@ReadLString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x22, 1, 4, "S", "AnsiString"); + return true; + } + //@ReadWString + if (SameText(name, "@ReadWString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x22, 1, 4, "S", "WideString"); + return true; + } + //@ReadUString + if (SameText(name, "@ReadUString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x22, 1, 4, "S", "UnicodeString"); + return true; + } + //@ReadWCString + if (SameText(name, "@ReadWCString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PWideChar"); + procInfo->AddArg(0x21, 2, 4, "MaxBytes", "Longint"); + return true; + } + //@ReadWChar + if (SameText(name, "@ReadWChar")) + { + kind = ikFunc; + type = "WideChar"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@ReadExt + if (SameText(name, "@ReadExt")) + { + //kind = ikFunc; + //type = "Extended"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@ReadLn + if (SameText(name, "@ReadLn")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@Rename + if (SameText(name, "@Rename")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "NewName", "PChar"); + return true; + } + //@ResetFile + if (SameText(name, "@ResetFile")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "RecSize", "Longint"); + return true; + } + //@ResetText + if (SameText(name, "@ResetText")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@RewritFile + if (SameText(name, "@RewritFile")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "RecSize", "Longint"); + return true; + } + //@RewritText + if (SameText(name, "@RewritText")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + //procInfo->AddArg(0x21, 1, 4, "recSize", "Longint"); + return true; + } + //@Seek + if (SameText(name, "@Seek")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "RecNum", "Longint"); + return true; + } + //@SeekEof + if (SameText(name, "@SeekEof")) + { + kind = ikFunc; + type = "Boolean"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@SeekEoln + if (SameText(name, "@SeekEoln")) + { + kind = ikFunc; + type = "Boolean"; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@SetTextBuf + if (SameText(name, "@SetTextBuf")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "P", "Pointer"); + procInfo->AddArg(0x21, 2, 4, "Size", "Longint"); + return true; + } + //@Truncate + if (SameText(name, "@Truncate")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + return true; + } + //@WriteRec + if (SameText(name, "@WriteRec")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); + procInfo->AddArg(0x21, 1, 4, "Buffer", "Pointer"); + return true; + } + //@WriteChar + if (SameText(name, "@WriteChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "C", "AnsiChar"); + procInfo->AddArg(0x21, 2, 4, "Width", "Integer"); + return true; + } + //@Write0Char + if (SameText(name, "@Write0Char")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "C", "AnsiChar"); + return true; + } + //@WriteBool + if (SameText(name, "@WriteBool")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "Val", "Boolean"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0Bool + if (SameText(name, "@Write0Bool")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "Val", "Boolean"); + return true; + } + //@WriteLong + if (SameText(name, "@WriteLong")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "Val", "Longint"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0Long + if (SameText(name, "@Write0Long")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "Val", "Longint"); + return true; + } + //@WriteString + if (SameText(name, "@WriteString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "ShortString"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0String + if (SameText(name, "@Write0String")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "ShortString"); + return true; + } + //@WriteCString + if (SameText(name, "@WriteCString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PAnsiChar"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0CString + if (SameText(name, "@Write0CString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PAnsiChar"); + return true; + } + //@WriteLString + if (SameText(name, "@WriteLString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "AnsiString"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0LString + if (SameText(name, "@Write0LString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "AnsiString"); + return true; + } + //@Write2Ext + if (SameText(name, "@Write2Ext") || + SameText(name, "@Str2Ext")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 8, 12, "Val", "Extended"); + procInfo->AddArg(0x21, 1, 4, "Width", "Longint"); + procInfo->AddArg(0x21, 2, 4, "Precision", "Longint"); + return true; + } + //@WriteWString + if (SameText(name, "@WriteWString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "WideString"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0WString + if (SameText(name, "@Write0WString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "WideString"); + return true; + } + //@WriteWCString + if (SameText(name, "@WriteWCString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PWideChar"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0WCString + if (SameText(name, "@Write0WCString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "PWideChar"); + return true; + } + //@WriteWChar + if (SameText(name, "@WriteWChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "C", "WideChar"); + procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); + return true; + } + //@Write0WChar + if (SameText(name, "@Write0WChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "C", "WideChar"); + return true; + } + //@Write1Ext + if (SameText(name, "@Write1Ext")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "Width", "Longint"); + return true; + } + //@Write0Ext + if (SameText(name, "@Write0Ext")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@WriteLn + if (SameText(name, "@WriteLn")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + return true; + } + //@WriteUString + if (SameText(name, "@WriteUString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "UnicodeString"); + procInfo->AddArg(0x21, 2, 4, "Width", "Integer"); + return true; + } + //@Write0UString + if (SameText(name, "@Write0UString")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "S", "UnicodeString"); + return true; + } + //@WriteVariant + if (SameText(name, "@WriteVariant")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "V", "TVarData"); + procInfo->AddArg(0x21, 2, 4, "Width", "Integer"); + return true; + } + //@Write0Variant + if (SameText(name, "@Write0Variant")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); + procInfo->AddArg(0x21, 1, 4, "V", "TVarData"); + return true; + } + //Other--------------------------------------------------------------------- + //A + //function @AsClass(child:TObject; parent:TClass):TObject; + if (SameText(name, "@AsClass")) + { + kind = ikFunc; + type = "TObject"; + procInfo->AddArg(0x21, 0, 4, "child", "TObject"); + procInfo->AddArg(0x21, 1, 4, "parent", "TClass"); + return true; + } + //procedure @Assert(Message: String; Filename:String; LineNumber:Integer); + if (SameText(name, "@Assert")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Message", "String"); + procInfo->AddArg(0x21, 1, 4, "Filename", "String"); + procInfo->AddArg(0x21, 2, 4, "LineNumber", "Integer"); + return true; + } + //@BoundErr + if (SameText(name, "@BoundErr")) + { + kind = ikProc; + return true; + } + //@CopyArray + if (SameText(name, "@CopyArray")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Dest", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "Source", "Pointer"); + procInfo->AddArg(0x21, 2, 4, "TypeInfo", "Pointer"); + procInfo->AddArg(0x21, 8, 4, "Cnt", "Integer"); + return true; + } + //@CopyRecord + if (SameText(name, "@CopyRecord")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Dest", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "Source", "Pointer"); + procInfo->AddArg(0x21, 2, 4, "TypeInfo", "Pointer"); + return true; + } + //DynArrays + //@DynArrayAddRef + if (SameText(name, "@DynArrayAddRef")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); + return true; + } + //@DynArrayAsg + if (SameText(name, "@DynArrayAsg")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "Source", "Pointer"); + procInfo->AddArg(0x21, 2, 4, "TypeInfo", "PDynArrayTypeInfo"); + return true; + } + //@DynArrayClear + if (SameText(name, "@DynArrayClear")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Arr", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); + return true; + } + //@DynArrayCopy + if (SameText(name, "@DynArrayCopy")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); + procInfo->AddArg(0x22, 2, 4, "Result", "Pointer"); + return true; + } + //@DynArrayCopyRange + if (SameText(name, "@DynArrayCopyRange")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); + procInfo->AddArg(0x21, 2, 4, "Index", "Integer"); + procInfo->AddArg(0x21, 8, 4, "Count", "Integer"); + procInfo->AddArg(0x22, 12, 4, "Result", "Pointer"); + return true; + } + //@DynArrayHigh + if (SameText(name, "@DynArrayHigh")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); + return true; + } + //@DynArrayLength + if (SameText(name, "@DynArrayLength")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); + return true; + } + //@DynArraySetLength + if (SameText(name, "@DynArraySetLength")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Arr", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); + procInfo->AddArg(0x21, 2, 4, "DimCnt", "Longint"); + procInfo->AddArg(0x21, 8, 4, "LengthVec", "Longint"); + return true; + } + //@FillChar + if (SameText(name, "@FillChar")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "dst", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "cnt", "Integer"); + procInfo->AddArg(0x21, 2, 4, "val", "Char"); + return true; + } + //@FreeMem + if (SameText(name, "@FreeMem")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x21, 0, 4, "p", "Pointer"); + return true; + } + //@GetMem + if (SameText(name, "@GetMem")) + { + kind = ikFunc; + type = "Pointer"; + procInfo->AddArg(0x21, 0, 4, "size", "Integer"); + return true; + } + //@IntOver + if (SameText(name, "@IntOver")) + { + kind = ikProc; + return true; + } + //@IsClass + if (SameText(name, "@IsClass")) + { + kind = ikFunc; + type = "Boolean"; + procInfo->AddArg(0x21, 0, 4, "Child", "TObject"); + procInfo->AddArg(0x21, 1, 4, "Parent", "TClass"); + return true; + } + //@RandInt + if (SameText(name, "@RandInt")) + { + kind = ikFunc; + type = "Integer"; + procInfo->AddArg(0x21, 0, 4, "Range", "Integer"); + return true; + } + //@ReallocMem + if (SameText(name, "@ReallocMem")) + { + kind = ikFunc; + type = "Pointer"; + procInfo->AddArg(0x22, 0, 4, "P", "Pointer"); + procInfo->AddArg(0x21, 1, 4, "NewSize", "Integer"); + return true; + } + //@SetElem + if (SameText(name, "@SetElem")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "Dest", "SET"); + procInfo->AddArg(0x21, 1, 1, "Elem", "Byte"); + procInfo->AddArg(0x21, 2, 1, "Size", "Byte"); + return true; + } + //Trunc + if (SameText(name, "@Trunc")) + { + kind = ikFunc; + type = "Int64"; + procInfo->AddArg(0x21, 0, 12, "X", "Extended"); + return true; + } + //V + //function @ValExt(s:AnsiString; var code:Integer):Extended; + if (SameText(name, "@ValExt")) + { + kind = ikProc; + procInfo->AddArg(0x21, 0, 4, "s", "AnsiString"); + procInfo->AddArg(0x22, 1, 4, "code", "Integer"); + return true; + } + //function @ValLong(s:AnsiString; var code:Integer):Longint; + if (SameText(name, "@ValLong")) + { + kind = ikFunc; + type = "Longint"; + procInfo->AddArg(0x21, 0, 4, "s", "AnsiString"); + procInfo->AddArg(0x22, 1, 4, "code", "Integer"); + return true; + } + //procedure @VarFromCurr(var v: Variant; val:Currency); + if (SameText(name, "@VarFromCurr")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "v", "Variant"); + //procInfo->AddArg(0x21, ?, 8, "val", "Currency"); + return true; + } + //procedure @VarFromReal(var v:Variant; val:Real); + if (SameText(name, "@VarFromReal")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "v", "Variant"); + //procInfo->AddArg(0x21, ?, 8, "val", "Real"); fld! + return true; + } + //procedure @VarFromTDateTime(var v: Variant; val:TDateTime); + if (SameText(name, "@VarFromTDateTime")) + { + kind = ikProc; + procInfo->AddArg(0x22, 0, 4, "v", "Variant"); + //procInfo->AddArg(0x21, ?, 8, "val", "TDateTime"); fld! + return true; + } + //SET + //procedure @SetRange(lo:Byte; hi:Byte; size:Byte; VAR d:SET); AL,DL,ECX,AH {Usage: d = [lo..hi]} + //function @SetEq(left:SET; right:SET; size:Byte):ZF; {Usage: left = right} + //function @SetLe(left:SET; right:SET; size:Byte):ZF; + //procedure @SetIntersect(var dest:SET; src:SET; size:Byte); + //procedure @SetIntersect3(var dest:SET; src:SET; size:Longint; src2:SET); + //procedure @SetUnion(var dest:SET; src:SET; size:Byte); + //procedure @SetUnion3(var dest:SET; src:SET; size:Longint; src2:SET); + //procedure @SetSub(var dest:SET; src:SET; size:Byte); + //procedure @SetSub3(var dest:SET; src:SET; size:Longint; src2:SET); + //procedure @SetExpand(src:SET; var dest:SET; lo:Byte; hi:Byte); EAX,EDX,CH,CL + //in <-> bt + return false; +} +//--------------------------------------------------------------------------- +/* +{ Procedures and functions that need compiler magic } +procedure _COS(st0):st0; +procedure _EXP(st1):st0; +procedure _INT; +procedure _SIN(st0):st0; +procedure _FRAC; +procedure _ROUND; + +function _RandExt:Extended; ST0 + +procedure _Str2Ext(val:Extended; width:Longint; precision:Longint; var s:String); [ESP+4],EAX,EDX,ECX +procedure _Str0Ext(val:Extended; var s:String); [ESP+4],EAX +procedure _Str1Ext(val:Extended; width:Longint; var s:String); [ESP+4],EAX,EDX +function _ValExt(s:AnsiString; var code:Integer):Extended; EAX,EDX:ST0 +function _Pow10(val:Extended; Power:Integer):Extended; ST0,EAX:ST0 +procedure _Real2Ext(val:Real):Extended; EAX:ST0 +procedure _Ext2Real(val:Extended):Real; ST0,EAX + +function _ObjSetup(Self:TObject; vmtPtrOff:Longint):TObject; AD //internal +procedure _ObjCopy(Dest:TObject; Src:TObject, vmtPtrOff:Longint); ADC //internal +function _Fail(Self:TObject; allocFlag:Longint):TObject; AD //internal + +function @_llmul(val1:Int64; val2:Int64):Int64; EAX;EDX;[ESP+4] +function @_llmulo(val1:Int64; val2:Int64):Int64,OF; EAX;EDX;[ESP+4] +function @_lldiv(val1:Int64; val2:Int64):Int64; EAX;EDX;[ESP+4] +function @_lldivo(val1:Int64; val2:Int64):Int64,OF; EAX;EDX;[ESP+4] +function @_llmod(val1:Int64; val2:Int64):Int64; EAX;EDX;[ESP+4] +function @_llshl(val:Int64):Int64; EAX,EDX +function @_llushr(val:Int64):Int64; EAX,EDX +*/ + diff --git a/Infos.h b/Infos.h new file mode 100644 index 0000000..2a664d2 --- /dev/null +++ b/Infos.h @@ -0,0 +1,152 @@ +//--------------------------------------------------------------------------- +#ifndef InfosH +#define InfosH + +#include "KnowledgeBase.h" +//--------------------------------------------------------------------------- +//lastVar +//vmtAdr +//typeIdx??? - for Type search +//--------------------------------------------------------------------------- +//Class Methods Information +typedef struct +{ + bool abstract; //call @AbstractError + char kind; //'M' - method; 'V' - virtual; 'D' - dynamic + int id; //ID (for virtual methods - offset, for dynamics - MsgId) + DWORD address; //Call Address + String name; //Method Name +} MethodRec, *PMethodRec; + +//Information about class fields (look VmtSelfPtr) +#define FIELD_PRIVATE 9 +#define FIELD_PROTECTED 10 +#define FIELD_PUBLIC 11 +#define FIELD_PUBLISHED 12 + +//--------------------------------------------------------------------------- +class InfoResStringInfo +{ +public: + String value; +}; + +typedef InfoResStringInfo *PInfoResStringInfo; + +class InfoVmtInfo +{ +public: + TStringList *interfaces; + TList *fields; + TList *methods; +public: + __fastcall InfoVmtInfo(); + __fastcall ~InfoVmtInfo(); + void __fastcall AddInterface(String Value); + PFIELDINFO __fastcall AddField(DWORD ProcAdr, int ProcOfs, BYTE Scope, int Offset, int Case, String Name, String Type); + bool __fastcall AddMethod(bool Abstract, char Kind, int Id, DWORD Address, String Name); + void __fastcall RemoveField(int Offset); +}; + +typedef InfoVmtInfo *PInfoVmtInfo; + +//procflags +#define PF_MAYBEEMBED 0x80000000 +#define PF_EMBED 0x40000000 +#define PF_VIRTUAL 0x20000000 +#define PF_DYNAMIC 0x10000000 +#define PF_EVENT 0x08000000 +#define PF_OUTEAX 0x04000000 +#define PF_KBPROTO 0x02000000 //if prototype for kb was got +#define PF_BPBASED 0x01000000 +#define PF_ARGSIZEG 0x00800000 //If delta between retN and total arguments size > 0 +#define PF_ARGSIZEL 0x00400000 //If delta between retN and total arguments size < 0 +#define PF_METHOD 0x00200000 //is method of class (other than virtual, dynamic or event) +#define PF_PUBLISHED 0x00100000 //published + +#define PF_ALLMETHODS (PF_METHOD | PF_VIRTUAL | PF_DYNAMIC | PF_EVENT) +//first 3 bits - call kind (1, 2, 3, 4) + +class InfoProcInfo +{ +public: + DWORD flags; + WORD bpBase; //First argument distance from base ebp + WORD retBytes; + int procSize; + int stackSize; + TList *args; + TList *locals; +public: + __fastcall InfoProcInfo(); + __fastcall ~InfoProcInfo(); + PARGINFO __fastcall AddArg(PARGINFO aInfo); + PARGINFO __fastcall AddArg(BYTE Tag, int Ofs, int Size, String Name, String TypeDef); + String __fastcall AddArgsFromDeclaration(char* Decl, int from, int callKind); + PARGINFO __fastcall GetArg(int n); + void __fastcall DeleteArg(int n); + void __fastcall DeleteArgs(); + PLOCALINFO __fastcall AddLocal(int Ofs, int Size, String Name, String TypeDef); + PLOCALINFO __fastcall GetLocal(int Ofs); + PLOCALINFO __fastcall GetLocal(String Name); + void __fastcall DeleteLocal(int n); + void __fastcall DeleteLocals(); + void __fastcall SetLocalType(int Ofs, String TypeDef); +}; + +typedef InfoProcInfo *PInfoProcInfo; + +#define OP_COMMENT 0x10 +#define OP_CALL 0x11 + +typedef struct +{ + BYTE Op; //Operation + union + { + int Offset; //Field offset + DWORD Address; //Proc address for OP_CALL + } Ofs; + String Name; //Type name +} PICODE, *PPICODE; + +class InfoRec +{ +public: + BYTE counter; + BYTE kind; + int kbIdx; + String type; //Return value type for function + PPICODE picode; //Internal code + TList *xrefs; + PInfoResStringInfo rsInfo; + PInfoVmtInfo vmtInfo; + PInfoProcInfo procInfo; +private: + String name; +public: + __fastcall InfoRec(int APos, BYTE AKind); + __fastcall ~InfoRec(); + bool __fastcall HasName(); + String __fastcall GetName(); + int __fastcall GetNameLength(); + void __fastcall SetName(String AValue); + void __fastcall ConcatName(String AValue); + bool __fastcall SameName(String AValue); + void __fastcall AddXref(char Type, DWORD Adr, int Offset); + void __fastcall DeleteXref(DWORD Adr); + void __fastcall ScanUpItemAndAddRef(int fromPos, DWORD itemAdr, char refType, DWORD refAdr); + virtual void __fastcall Save(FILE* outs);//virtual void __fastcall Save(TStream* outs); + virtual void __fastcall Load(FILE* ins, char* buf);//virtual void __fastcall Load(TStream* ins, char* buf); + //virtual void __fastcall Skip(TStream* ins, char* buf, BYTE asKind); + String __fastcall MakePrototype(int adr, bool showKind, bool showTail, bool multiline, bool fullName, bool allArgs); + String __fastcall MakeDelphiPrototype(int Adr, PMethodRec recM); + String __fastcall MakeMultilinePrototype(int Adr, int* ArgsBytes, String MethodType); + String __fastcall MakeMapName(int Adr); + bool __fastcall MakeArgsManually(); + String __fastcall MakeCppPrototype(int Adr, String FType); +}; + +typedef InfoRec *PInfoRec; +//--------------------------------------------------------------------------- +#endif diff --git a/InputDlg.cpp b/InputDlg.cpp new file mode 100644 index 0000000..f01041b --- /dev/null +++ b/InputDlg.cpp @@ -0,0 +1,31 @@ +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "InputDlg.h" +#include "Misc.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +TFInputDlg_11011981 *FInputDlg_11011981; +//--------------------------------------------------------------------- +__fastcall TFInputDlg_11011981::TFInputDlg_11011981(TComponent* AOwner) + : TForm(AOwner) +{ +} +//--------------------------------------------------------------------- +void __fastcall TFInputDlg_11011981::FormShow(TObject *Sender) +{ + if (edtName->CanFocus()) ActiveControl = edtName; +} +//--------------------------------------------------------------------------- +void __fastcall TFInputDlg_11011981::edtNameEnter(TObject *Sender) +{ + edtName->SelectAll(); +} +//--------------------------------------------------------------------------- +void __fastcall TFInputDlg_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/InputDlg.dfm b/InputDlg.dfm similarity index 89% rename from Sources/Forms/InputDlg.dfm rename to InputDlg.dfm index f4b9a35..9279a00 100644 --- a/Sources/Forms/InputDlg.dfm +++ b/InputDlg.dfm @@ -11,7 +11,7 @@ object FInputDlg_11011981: TFInputDlg_11011981 OnCreate = FormCreate OnShow = FormShow PixelsPerInch = 120 - TextHeight = 13 + TextHeight = 16 object OKBtn: TButton Left = 252 Top = 49 @@ -39,8 +39,8 @@ object FInputDlg_11011981: TFInputDlg_11011981 Top = 10 Width = 503 Height = 28 - EditLabel.Width = 43 - EditLabel.Height = 17 + EditLabel.Width = 50 + EditLabel.Height = 20 EditLabel.Caption = 'Name:' EditLabel.Font.Charset = RUSSIAN_CHARSET EditLabel.Font.Color = clWindowText @@ -54,6 +54,7 @@ object FInputDlg_11011981: TFInputDlg_11011981 Font.Name = 'Fixedsys' Font.Style = [] LabelPosition = lpLeft + LabelSpacing = 3 ParentFont = False TabOrder = 2 OnEnter = edtNameEnter diff --git a/InputDlg.h b/InputDlg.h new file mode 100644 index 0000000..d9d5d0c --- /dev/null +++ b/InputDlg.h @@ -0,0 +1,32 @@ +//---------------------------------------------------------------------------- +#ifndef InputDlgH +#define InputDlgH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TFInputDlg_11011981 : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TLabeledEdit *edtName; + void __fastcall FormShow(TObject *Sender); + void __fastcall edtNameEnter(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: +public: + virtual __fastcall TFInputDlg_11011981(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +extern PACKAGE TFInputDlg_11011981 *FInputDlg_11011981; +//---------------------------------------------------------------------------- +#endif diff --git a/KBViewer.cpp b/KBViewer.cpp new file mode 100644 index 0000000..c18ebda --- /dev/null +++ b/KBViewer.cpp @@ -0,0 +1,354 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "KBViewer.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" + +#include "Disasm.h" +#include "KnowledgeBase.h" +#include "Main.h" +#include "Misc.h" + +extern DWORD CodeBase; +extern DWORD CurProcAdr; +extern DWORD CurUnitAdr; +extern MDisasm Disasm; +extern BYTE *Code; +extern PInfoRec *Infos; +extern MKnowledgeBase KnowledgeBase; +extern TList *VmtList; +extern TList *OwnTypeList; + +TFKBViewer_11011981 *FKBViewer_11011981; +//--------------------------------------------------------------------------- +__fastcall TFKBViewer_11011981::TFKBViewer_11011981(TComponent* Owner) + : TForm(Owner) +{ + UnitsNum = 0; + CurrIdx = -1; + CurrAdr = 0; + FromIdx = 0; + ToIdx = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::FormCreate(TObject *Sender) +{ + lbIDR->Canvas->Font->Assign(lbIDR->Font); + lbKB->Canvas->Font->Assign(lbKB->Font); + ScaleForm(this); +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::ShowCode(DWORD adr, int idx) +{ + bool outfixup; + int n, m, wid, maxwid, row; + int _firstProcIdx, _lastProcIdx; + DWORD Val, Adr; + TCanvas* canvas; + String line; + DISINFO DisInfo; + char disLine[100]; + + CurrIdx = idx; + CurrAdr = adr; + edtCurrIdx->Text = String(CurrIdx); + lPosition->Caption = String(CurrIdx - Position); + + lbIDR->Clear(); + canvas = lbIDR->Canvas; maxwid = 0; + for (m = 0; m < FMain_11011981->lbCode->Count; m++) + { + line = FMain_11011981->lbCode->Items->Strings[m]; + //Ignore first byte (for symbol <) + int _bytes = line.Length() - 1; + //If instruction, ignore flags (last byte) + if (m) _bytes --; + //Extract original instruction + line = line.SubString(2, _bytes); + //For first row add prefix IDR: + if (!m) line = "IDR:" + line; + lbIDR->Items->Add(line); + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + } + lbIDR->ScrollWidth = maxwid + 2; + + lbKB->Clear(); row = 0; + MProcInfo aInfo; + MProcInfo *pInfo = &aInfo; + maxwid = 0; + if (KnowledgeBase.GetProcInfo(CurrIdx, INFO_DUMP, pInfo)) + { + cbUnits->Text = KnowledgeBase.GetModuleName(pInfo->ModuleID); + KnowledgeBase.GetProcIdxs(pInfo->ModuleID, &_firstProcIdx, &_lastProcIdx); + lblKbIdxs->Caption = String(_firstProcIdx) + " - " + String(_lastProcIdx); + + canvas = lbKB->Canvas; + + line = "KB:" + pInfo->ProcName; + lbKB->Items->Add(line); row++; + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + + int instrLen, pos = 0; + DWORD curAdr = adr; + + if (pInfo->FixupNum) + { + char *p = pInfo->Dump + 2*pInfo->DumpSz; + + for (n = 0; n < pInfo->FixupNum; n++) + { + char fixupType = *p; p++; + int fixupOfs = *((DWORD*)p); p += 4; + WORD len = *((WORD*)p); p += 2; + String fixupName = String(p, len); p += len + 1; + + while (pos <= fixupOfs && pos < pInfo->DumpSz) + { + instrLen = Disasm.Disassemble(pInfo->Dump + pos, (__int64)curAdr, &DisInfo, disLine); + if (!instrLen) + { + //return; + lbKB->Items->Add(Val2Str8(curAdr) + " ???"); row++; + pos++; curAdr++; + continue; + } + + BYTE op = Disasm.GetOp(DisInfo.Mnem); + line = Val2Str8(curAdr) + " " + disLine; + outfixup = false; + if (pos + instrLen > fixupOfs) + { + if (DisInfo.Call) + { + line = Val2Str8(curAdr) + " call "; + outfixup = true; + } + else if (op == OP_JMP) + line = Val2Str8(curAdr) + " jmp "; + else + line += ";"; + if (!SameText(fixupName, pInfo->ProcName)) + { + line += fixupName; + } + else + { + Val = *((DWORD*)(Code + Adr2Pos(CurrAdr) + fixupOfs)); + if (fixupType == 'J') + Adr = CurrAdr + fixupOfs + Val + 4; + else + Adr = Val; + + line += Val2Str8(Adr); + } + } + + lbKB->Items->Add(line); + if (outfixup) lbKB->Selected[row] = true; + row++; + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + + pos += instrLen; + curAdr += instrLen; + } + } + } + while (pos < pInfo->DumpSz) + { + instrLen = Disasm.Disassemble(pInfo->Dump + pos, (__int64)curAdr, &DisInfo, disLine); + if (!instrLen) + { + lbKB->Items->Add(Val2Str8(curAdr) + " ???"); + pos++; curAdr++; + continue; + } + line = Val2Str8(curAdr) + " " + disLine; + lbKB->Items->Add(line); + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + + pos += instrLen; + curAdr += instrLen; + } + } + lbKB->ScrollWidth = maxwid + 2; + lbKB->TopIndex = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::bPrevClick(TObject *Sender) +{ + if (CurrIdx != -1) ShowCode(CurrAdr, CurrIdx - 1); +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::bNextClick(TObject *Sender) +{ + if (CurrIdx != -1) ShowCode(CurrAdr, CurrIdx + 1); +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::btnOkClick(TObject *Sender) +{ + int m, k1, k2, ap, pos, pos1, pos2, Idx, val; + DWORD adr; + MProcInfo aInfo; + MProcInfo *pInfo = &aInfo; + PInfoRec recN; + String kbName, idrName, kbLine, idrLine; + + + if (KnowledgeBase.GetProcInfo(CurrIdx, INFO_DUMP | INFO_ARGS, pInfo)) + { + adr = CurProcAdr; ap = Adr2Pos(adr); + if (ap < 0) return; + recN = GetInfoRec(adr); + if (!recN) return; + recN->procInfo->DeleteArgs(); + FMain_11011981->StrapProc(ap, CurrIdx, pInfo, false, FMain_11011981->EstimateProcSize(CurProcAdr)); + //Strap all selected items (in IDR list box) + if (lbKB->SelCount == lbIDR->SelCount) + { + k1 = 0; k2 = 0; + for (m = 0; m < lbKB->SelCount; m++) + { + kbLine = ""; idrLine = ""; + for (; k1 < lbKB->Items->Count; k1++) + { + if (lbKB->Selected[k1]) + { + kbLine = lbKB->Items->Strings[k1]; k1++; + break; + } + } + for (; k2 < lbIDR->Items->Count; k2++) + { + if (lbIDR->Selected[k2]) + { + idrLine = lbIDR->Items->Strings[k2]; k2++; + break; + } + } + if (kbLine != "" && idrLine != "") + { + pos1 = kbLine.Pos("call"); + pos2 = idrLine.Pos("call"); + if (pos1 && pos2) + { + kbName = kbLine.SubString(pos1 + 4, kbLine.Length()).Trim(); + idrName = idrLine.SubString(pos2 + 4, idrLine.Length()).Trim(); + pos = idrName.Pos(";"); + if (pos) idrName = idrName.SubString(1, pos - 1); + adr = 0; + if (TryStrToInt(String("$") + idrName, val)) adr = val; + ap = Adr2Pos(adr); + if (kbName != "" && ap >= 0) + { + recN = GetInfoRec(adr); + recN->procInfo->DeleteArgs(); + + WORD *uses = KnowledgeBase.GetModuleUses(KnowledgeBase.GetModuleID(cbUnits->Text.c_str())); + Idx = KnowledgeBase.GetProcIdx(uses, kbName.c_str(), Code + ap); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + FMain_11011981->StrapProc(ap, Idx, pInfo, true, pInfo->DumpSz); + } + } + else + { + Idx = KnowledgeBase.GetProcIdx(uses, kbName.c_str(), 0); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + FMain_11011981->StrapProc(ap, Idx, pInfo, false, FMain_11011981->EstimateProcSize(adr)); + } + } + } + } + } + } + } + } + FMain_11011981->RedrawCode(); + FMain_11011981->ShowUnitItems(FMain_11011981->GetUnit(CurUnitAdr), FMain_11011981->lbUnitItems->TopIndex, FMain_11011981->lbUnitItems->ItemIndex); + } + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::btnCancelClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::edtCurrIdxChange(TObject *Sender) +{ + try + { + ShowCode(CurrAdr, StrToInt(edtCurrIdx->Text)); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::cbUnitsChange(TObject *Sender) +{ + WORD _moduleID; + int k, _firstProcIdx, _lastProcIdx, _idx; + MProcInfo _aInfo; + MProcInfo *_pInfo = &_aInfo; + + Position = -1; + _moduleID = KnowledgeBase.GetModuleID(cbUnits->Text.c_str()); + if (_moduleID != 0xFFFF) + { + if (KnowledgeBase.GetProcIdxs(_moduleID, &_firstProcIdx, &_lastProcIdx)) + { + edtCurrIdx->Text = String(_firstProcIdx); + lblKbIdxs->Caption = String(_firstProcIdx) + " - " + String(_lastProcIdx); + for (k = _firstProcIdx; k <= _lastProcIdx; k++) + { + _idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(_idx)) + { + if (KnowledgeBase.GetProcInfo(_idx, INFO_DUMP | INFO_ARGS, _pInfo)) + { + if (MatchCode(Code + Adr2Pos(CurProcAdr), _pInfo)) + { + edtCurrIdx->Text = String(_idx); + Position = _idx; + break; + } + } + } + } + } + } + if (Position == -1) + ShowCode(CurProcAdr, _firstProcIdx); + else + ShowCode(CurProcAdr, Position); +} +//--------------------------------------------------------------------------- +void __fastcall TFKBViewer_11011981::FormShow(TObject *Sender) +{ + if (!UnitsNum) + { + for (int n = 0; n < KnowledgeBase.ModuleCount; n++) + { + int ID = KnowledgeBase.ModuleOffsets[n].NamId; + const BYTE *p = KnowledgeBase.GetKBCachePtr(KnowledgeBase.ModuleOffsets[ID].Offset, KnowledgeBase.ModuleOffsets[ID].Size); + cbUnits->Items->Add(String((char*)(p + 4))); + UnitsNum++; + } + } +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/KBViewer.dfm b/KBViewer.dfm similarity index 94% rename from Sources/Forms/KBViewer.dfm rename to KBViewer.dfm index 1b59623..770cc00 100644 --- a/Sources/Forms/KBViewer.dfm +++ b/KBViewer.dfm @@ -21,7 +21,9 @@ object FKBViewer_11011981: TFKBViewer_11011981 object Splitter1: TSplitter Left = 465 Top = 33 + Width = 3 Height = 693 + Cursor = crHSplit Align = alNone end object lbKB: TListBox @@ -203,6 +205,7 @@ object FKBViewer_11011981: TFKBViewer_11011981 Font.Height = -13 Font.Name = 'MS Sans Serif' Font.Style = [fsBold] + ItemHeight = 16 ParentFont = False TabOrder = 0 OnChange = cbUnitsChange diff --git a/KBViewer.h b/KBViewer.h new file mode 100644 index 0000000..57315d2 --- /dev/null +++ b/KBViewer.h @@ -0,0 +1,52 @@ +//--------------------------------------------------------------------------- + +#ifndef KBViewerH +#define KBViewerH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFKBViewer_11011981 : public TForm +{ +__published: // IDE-managed Components + TListBox *lbKB; + TListBox *lbIDR; + TPanel *Panel3; + TButton *bPrev; + TButton *bNext; + TButton *btnOk; + TButton *btnCancel; + TLabel *lPosition; + TSplitter *Splitter1; + TEdit *edtCurrIdx; + TLabel *lKBIdx; + TPanel *Panel1; + TComboBox *cbUnits; + TLabel *Label1; + TLabel *lblKbIdxs; + void __fastcall bPrevClick(TObject *Sender); + void __fastcall bNextClick(TObject *Sender); + void __fastcall btnOkClick(TObject *Sender); + void __fastcall btnCancelClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall edtCurrIdxChange(TObject *Sender); + void __fastcall cbUnitsChange(TObject *Sender); + void __fastcall FormShow(TObject *Sender); +private: // User declarations + int UnitsNum; + int CurrIdx; + DWORD CurrAdr; +public: // User declarations + int Position; + DWORD FromIdx;//First Unit idx + DWORD ToIdx; //Last Unit idx + __fastcall TFKBViewer_11011981(TComponent* Owner); + void __fastcall ShowCode(DWORD adr, int idx); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFKBViewer_11011981 *FKBViewer_11011981; +//--------------------------------------------------------------------------- +#endif diff --git a/KnowledgeBase.cpp b/KnowledgeBase.cpp new file mode 100644 index 0000000..632ffe1 --- /dev/null +++ b/KnowledgeBase.cpp @@ -0,0 +1,2183 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include "KnowledgeBase.h" + +#include "Main.h" +#include "Misc.h" +//--------------------------------------------------------------------------- +extern DWORD CodeBase; +extern BYTE *Code; + String __fastcall TrimTypeName(const String& TypeName); +//--------------------------------------------------------------------------- +#define cfCode 0x00000001 //Áàéò îòíîñèòñÿ ê êîäó +#define cfData 0x00000002 //Áàéò îòíîñèòñÿ ê äàííûì +FIELDINFO::~FIELDINFO() +{ + CleanupList(xrefs); +} +//--------------------------------------------------------------------------- +__fastcall MConstInfo::MConstInfo() +{ + ModuleID = 0xFFFF; + ConstName = ""; + Type = 0; + TypeDef = ""; + Value = ""; + DumpSz = 0; + FixupNum = 0; + Dump = 0; +} +//--------------------------------------------------------------------------- +__fastcall MConstInfo::~MConstInfo() +{ + //as direct cache mem usage + //if (Dump) delete[] Dump; +} +//--------------------------------------------------------------------------- +__fastcall MTypeInfo::MTypeInfo() +{ + Size = 0; + ModuleID = 0xFFFF; + TypeName = ""; + Kind = 0xFF; + VMCnt = 0; + Decl = ""; + DumpSz = 0; + FixupNum = 0; + Dump = 0; + FieldsNum = 0; + Fields = 0; + PropsNum = 0; + Props = 0; + MethodsNum = 0; + Methods = 0; +} +//--------------------------------------------------------------------------- +__fastcall MTypeInfo::~MTypeInfo() +{ +} +//--------------------------------------------------------------------------- +__fastcall MVarInfo::MVarInfo() +{ + ModuleID = 0xFFFF; + VarName = ""; + Type = 0; + TypeDef = ""; + AbsName = ""; +} +//--------------------------------------------------------------------------- +__fastcall MVarInfo::~MVarInfo() +{ +} +//--------------------------------------------------------------------------- +__fastcall MResStrInfo::MResStrInfo() +{ + ModuleID = 0xFFFF; + ResStrName = ""; + TypeDef = ""; + //AContext = ""; +} +//--------------------------------------------------------------------------- +__fastcall MResStrInfo::~MResStrInfo() +{ +} +//--------------------------------------------------------------------------- +__fastcall MProcInfo::MProcInfo() +{ + ModuleID = 0xFFFF; + ProcName = ""; + Embedded = false; + DumpType = 0; + MethodKind = 0; + CallKind = 0; + VProc = 0; + TypeDef = ""; + DumpSz = 0; + FixupNum = 0; + Dump = 0; + ArgsNum = 0; + Args = 0; + //LocalsNum = 0; + //Locals = 0; +} +//--------------------------------------------------------------------------- +__fastcall MProcInfo::~MProcInfo() +{ +} +//--------------------------------------------------------------------------- +__fastcall MKnowledgeBase::MKnowledgeBase() +{ + Inited = false; + Version = 0.0; + Handle = 0; + + Mods = 0; + ModuleOffsets = 0; + ConstOffsets = 0; + TypeOffsets = 0; + VarOffsets = 0; + ResStrOffsets = 0; + ProcOffsets = 0; + UsedProcs = 0; + + KBCache = 0; + SizeKBFile = 0; + NameKBFile = ""; +} +//--------------------------------------------------------------------------- +__fastcall MKnowledgeBase::~MKnowledgeBase() +{ + Close(); +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::CheckKBFile() +{ + bool _isMSIL; + int _delphiVer; + DWORD _crc; + DWORD _kbVer; + char _signature[24]; + char _description[256]; + + fread(_signature, 1, 24, Handle); + fread(&_isMSIL, sizeof(_isMSIL), 1, Handle); + fread(&_delphiVer, sizeof(_delphiVer), 1, Handle); + fread(&_crc, sizeof(_crc), 1, Handle); + fread(_description, 1, 256, Handle); + fread(&_kbVer, sizeof(_kbVer), 1, Handle); + //Old format + if (!strcmp(_signature, "IDD Knowledge Base File") && _kbVer == 1) + { + Version = _kbVer; + return true; + } + //New format + if (!strcmp(_signature, "IDR Knowledge Base File") && _kbVer == 2) + { + Version = _kbVer; + return true; + } + return false; +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::Open(char* filename) +{ + if (Inited) + { + if (NameKBFile == String(filename)) + return true; + Close(); + } + + Inited = false; + Handle = fopen(filename, "rb"); + if (!Handle) return false; + + if (!CheckKBFile()) + { + fclose(Handle); + Handle = 0; + return false; + } + + fseek(Handle, -4L, SEEK_END); + //Read SectionsOffset + fread(&SectionsOffset, sizeof(SectionsOffset), 1, Handle); + //Seek at SectionsOffset + fseek(Handle, SectionsOffset, SEEK_SET); + + //Read section Modules + fread(&ModuleCount, sizeof(ModuleCount), 1, Handle); + Mods = new WORD[ModuleCount + 1]; + memset(Mods, 0xFF, (ModuleCount + 1)*sizeof(WORD)); + fread(&MaxModuleDataSize, sizeof(MaxModuleDataSize), 1, Handle); + ModuleOffsets = new OFFSETSINFO[ModuleCount]; + fread(ModuleOffsets, sizeof(OFFSETSINFO), ModuleCount, Handle); + //Read section Consts + fread(&ConstCount, sizeof(ConstCount), 1, Handle); + fread(&MaxConstDataSize, sizeof(MaxConstDataSize), 1, Handle); + ConstOffsets = new OFFSETSINFO[ConstCount]; + fread((BYTE*)ConstOffsets, sizeof(OFFSETSINFO), ConstCount, Handle); + //Read section Types + fread(&TypeCount, sizeof(TypeCount), 1, Handle); + fread(&MaxTypeDataSize, sizeof(MaxTypeDataSize), 1, Handle); + TypeOffsets = new OFFSETSINFO[TypeCount]; + fread((BYTE*)TypeOffsets, sizeof(OFFSETSINFO), TypeCount, Handle); + //Read section Vars + fread(&VarCount, sizeof(VarCount), 1, Handle); + fread(&MaxVarDataSize, sizeof(MaxVarDataSize), 1, Handle); + VarOffsets = new OFFSETSINFO[VarCount]; + fread((BYTE*)VarOffsets, sizeof(OFFSETSINFO), VarCount, Handle); + //Read section ResStr + fread(&ResStrCount, sizeof(ResStrCount), 1, Handle); + fread(&MaxResStrDataSize, sizeof(MaxResStrDataSize), 1, Handle); + ResStrOffsets = new OFFSETSINFO[ResStrCount]; + fread((BYTE*)ResStrOffsets, sizeof(OFFSETSINFO), ResStrCount, Handle); + //Read section Procs + fread(&ProcCount, sizeof(ProcCount), 1, Handle); + fread(&MaxProcDataSize, sizeof(MaxProcDataSize), 1, Handle); + ProcOffsets = new OFFSETSINFO[ProcCount]; + fread((BYTE*)ProcOffsets, sizeof(OFFSETSINFO), ProcCount, Handle); + UsedProcs = new BYTE[ProcCount]; + memset(UsedProcs, 0, ProcCount); + + //as global KB file cache in RAM (speed up 3..4 times!) + fseek(Handle, 0L, SEEK_END); + SizeKBFile = ftell(Handle); + if (SizeKBFile > 0) + { + KBCache = new BYTE[SizeKBFile]; + if (KBCache) + { + fseek(Handle, 0L, SEEK_SET); + fread((BYTE*)KBCache, 1, SizeKBFile, Handle); + } + } + fclose(Handle); Handle = 0; + + NameKBFile = String(filename); + Inited = true; + return true; +} +//--------------------------------------------------------------------------- +void __fastcall MKnowledgeBase::Close() +{ + if (Inited) + { + if (Mods) delete[] Mods; + if (ModuleOffsets) delete[] ModuleOffsets; + if (ConstOffsets) delete[] ConstOffsets; + if (TypeOffsets) delete[] TypeOffsets; + if (VarOffsets) delete[] VarOffsets; + if (ResStrOffsets) delete[] ResStrOffsets; + if (ProcOffsets) delete[] ProcOffsets; + if (UsedProcs) delete[] UsedProcs; + + //as + if (KBCache) delete[] KBCache; + Inited = false; + } +} +//--------------------------------------------------------------------------- +WORD __fastcall MKnowledgeBase::GetModuleID(char* ModuleName) +{ + if (!Inited) return 0xFFFF; + + if (!ModuleName || !*ModuleName || !ModuleCount) return 0xFFFF; + + int ID, F = 0, L = ModuleCount - 1; + const BYTE* p; + while (F < L) + { + int M = (F + L)/2; + ID = ModuleOffsets[M].NamId; + p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); + if (stricmp(ModuleName, p + 4) <= 0) + L = M; + else + F = M + 1; + } + ID = ModuleOffsets[L].NamId; + p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); + if (!stricmp(ModuleName, p + 4)) return *((WORD*)p); + return 0xFFFF; +} +//--------------------------------------------------------------------------- +String __fastcall MKnowledgeBase::GetModuleName(WORD ModuleID) +{ + if (!Inited) return ""; + + if (ModuleID == 0xFFFF || !ModuleCount) return ""; + + int ID, F = 0, L = ModuleCount - 1; + const BYTE* p; + WORD ModID; + while (F < L) + { + int M = (F + L)/2; + ID = ModuleOffsets[M].ModId; + p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModuleID <= ModID) + L = M; + else + F = M + 1; + } + ID = ModuleOffsets[L].ModId; + p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModuleID == ModID) return String((char*)(p + 4)); + return ""; +} +//--------------------------------------------------------------------------- +//Return modules ids list containing given proc +void __fastcall MKnowledgeBase::GetModuleIdsByProcName(char* AProcName) +{ + Mods[0] = 0xFFFF; + + if (!Inited) return; + + if (!AProcName || !*AProcName || !ProcCount) return; + + int L = 0, R = ProcCount - 1, n; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + int res = stricmp(AProcName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(AProcName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(AProcName, p + 4); + if (res) break; + } + + n = 0; + for (int N = LN + 1; N < RN; N++) + { + ID = ProcOffsets[N].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + Mods[n] = *((WORD*)p); n++; + } + Mods[n] = 0xFFFF; + return; + } + if (L > R) return; + } +} +//--------------------------------------------------------------------------- +//Return sections containing given ItemName +int __fastcall MKnowledgeBase::GetItemSection(WORD* ModuleIDs, char* ItemName) +{ + bool found; + int L, R, M, ID, N, LN, RN, Result = KB_NO_SECTION; + + if (!Inited) return Result; + + if (!ItemName ||*ItemName == 0) return Result; + WORD ModuleID, ModID; + //CONST + if (ConstCount) + { + L = 0; R = ConstCount - 1; + while (1) + { + M = (L + R)/2; + ID = ConstOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + int res = stricmp(ItemName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ConstOffsets[LN].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ConstCount; RN++) + { + ID = ConstOffsets[RN].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + found = false; + for (N = LN + 1; N < RN; N++) + { + ID = ConstOffsets[N].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + ModID = *((WORD*)p); + for (int n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) + { + Result |= KB_CONST_SECTION; + found = true; + break; + } + } + if (found) break; + } + break; + } + if (L > R) break; + } + } + //TYPE + if (TypeCount) + { + L = 0; R = TypeCount - 1; + while (1) + { + M = (L + R)/2; + ID = TypeOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + int res = stricmp(ItemName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = TypeOffsets[LN].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + res = stricmp(ItemName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < TypeCount; RN++) + { + ID = TypeOffsets[RN].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + res = stricmp(ItemName, p + 4); + if (res) break; + } + found = false; + for (N = LN + 1; N < RN; N++) + { + ID = TypeOffsets[N].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + ModID = *((WORD*)p); + for (int n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) + { + Result |= KB_TYPE_SECTION; + found = true; + break; + } + } + if (found) break; + } + break; + } + if (L > R) break; + } + } + //VAR + if (VarCount) + { + L = 0; R = VarCount - 1; + while (1) + { + M = (L + R)/2; + ID = VarOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + int res = stricmp(ItemName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = VarOffsets[LN].NamId; + p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < VarCount; RN++) + { + ID = VarOffsets[RN].NamId; + p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + found = false; + for (N = LN + 1; N < RN; N++) + { + ID = VarOffsets[N].NamId; + p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + ModID = *((WORD*)p); + for (int n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) + { + Result |= KB_VAR_SECTION; + found = true; + break; + } + } + if (found) break; + } + break; + } + if (L > R) break; + } + } + //RESSTR + if (ResStrCount) + { + L = 0; R = ResStrCount - 1; + while (1) + { + M = (L + R)/2; + ID = ResStrOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + int res = stricmp(ItemName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ResStrOffsets[LN].NamId; + p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ResStrCount; RN++) + { + ID = ResStrOffsets[RN].NamId; + p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + found = false; + for (N = LN + 1; N < RN; N++) + { + ID = ResStrOffsets[N].NamId; + p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + ModID = *((WORD*)p); + for (int n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) + { + Result |= KB_RESSTR_SECTION; + found = true; + break; + } + } + if (found) break; + } + break; + } + if (L > R) break; + } + } + //PROC + if (ProcCount) + { + L = 0; R = ProcCount - 1; + while (1) + { + M = (L + R)/2; + ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + int res = stricmp(ItemName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ItemName, p + 4); + if (res) break; + } + found = false; + for (N = LN + 1; N < RN; N++) + { + ID = ProcOffsets[N].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + for (int n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) + { + Result |= KB_PROC_SECTION; + found = true; + break; + } + } + if (found) break; + } + break; + } + if (L > R) break; + } + } + return Result; +} +//--------------------------------------------------------------------------- +//Return constant index by name in given ModuleID +int __fastcall MKnowledgeBase::GetConstIdx(WORD* ModuleIDs, char* ConstName) +{ + if (!Inited) return -1; + + if (!ModuleIDs || !ConstName || !*ConstName || !ConstCount) return -1; + + WORD ModuleID, ModID; + int n, L = 0, R = ConstCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ConstOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + int res = stricmp(ConstName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ConstOffsets[LN].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + res = stricmp(ConstName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ConstCount; RN++) + { + ID = ConstOffsets[RN].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + res = stricmp(ConstName, p + 4); + if (res) break; + } + for (int N = LN + 1; N < RN; N++) + { + ID = ConstOffsets[N].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + ModID = *((WORD*)p); + + for (n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) return N; + } + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetConstIdxs(char* ConstName, int* ConstIdx) +{ + *ConstIdx = -1; + + if (!Inited) return 0; + + if (!ConstName ||!*ConstName || !ConstCount) return 0; + + int L = 0, R = ConstCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ConstOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + int res = stricmp(ConstName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int Num = 1; + *ConstIdx = M; + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ConstOffsets[LN].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + if (stricmp(ConstName, p + 4)) break; + Num++; + } + //Find right boundary + for (RN = M + 1; RN < ConstCount; RN++) + { + ID = ConstOffsets[RN].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + if (stricmp(ConstName, p + 4)) break; + Num++; + } + return Num; + } + if (L > R) return 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetTypeIdxByModuleIds(WORD* ModuleIDs, char* TypeName) +{ + if (!Inited) return -1; + + if (!ModuleIDs || !TypeName || !*TypeName || !TypeCount) return -1; + + WORD ModuleID, ModID; + int n, L = 0, R = TypeCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = TypeOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + int res = stricmp(TypeName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = TypeOffsets[LN].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + res = stricmp(TypeName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < TypeCount; RN++) + { + ID = TypeOffsets[RN].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + res = stricmp(TypeName, p + 4); + if (res) break; + } + for (int N = LN + 1; N < RN; N++) + { + ID = TypeOffsets[N].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + ModID = *((WORD*)p); + + for (n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) return N; + } + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetTypeIdxsByName(char* TypeName, int* TypeIdx) +{ + *TypeIdx = -1; + + if (!Inited) return 0; + + if (!TypeName || !*TypeName || !TypeCount) return 0; + + int L = 0, R = TypeCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = TypeOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + int res = stricmp(TypeName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int Num = 1; + *TypeIdx = M; + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = TypeOffsets[LN].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + if (stricmp(TypeName, p + 4)) break; + Num++; + } + //Find right boundary + for (RN = M + 1; RN < TypeCount; RN++) + { + ID = TypeOffsets[RN].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + if (stricmp(TypeName, p + 4)) break; + Num++; + } + return Num; + } + if (L > R) return 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetTypeIdxByUID(char* UID) +{ +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetVarIdx(WORD* ModuleIDs, char* VarName) +{ + if (!Inited) return -1; + + if (!ModuleIDs || !VarName || !*VarName || !VarCount) return -1; + + WORD ModuleID, ModID, len; + int n, L = 0, R = VarCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = VarOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + int res = stricmp(VarName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = VarOffsets[LN].NamId; + p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + res = stricmp(VarName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < VarCount; RN++) + { + ID = VarOffsets[RN].NamId; + p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + res = stricmp(VarName, p + 4); + if (res) break; + } + for (int N = LN + 1; N < RN; N++) + { + ID = VarOffsets[N].NamId; + p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); + ModID = *((WORD*)p); + for (n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) return N; + } + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetResStrIdx(int from, char* ResStrContext) +{ + if (!Inited) return -1; + + if (!ResStrContext || !*ResStrContext || !ResStrCount) return -1; + + int n, ID; + for (n = from; n < ResStrCount; n++) + { + ID = ResStrOffsets[n].NamId; + const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + //ModuleID + p += 2; + //ResStrName + WORD len = *((WORD*)p); p += len + 3; + //TypeDef + len = *((WORD*)p); p += len + 5; + //Context + if (!stricmp(ResStrContext, p)) + { + return n; + } + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetResStrIdx(WORD ModuleID, char* ResStrContext) +{ + if (!Inited) return -1; + + if (!ResStrContext || !*ResStrContext || !ResStrCount) return -1; + + WORD ModID, len; + int n, ID; + + for (n = 0; n < ResStrCount; n++) + { + ID = ResStrOffsets[n].NamId; + const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + //ModuleID + ModID = *((WORD*)p); p += 2; + //ResStrName + len = *((WORD*)p); p += len + 3; + //TypeDef + len = *((WORD*)p); p += len + 5; + //Context + if (ModuleID == ModID && !stricmp(ResStrContext, p)) + { + return n; + } + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetResStrIdx(WORD* ModuleIDs, char* ResStrName) +{ + if (!Inited) return -1; + + if (!ModuleIDs || !ResStrName || !*ResStrName || !ResStrCount) return -1; + + WORD ModuleID, ModID, len; + int n, L = 0, R = ResStrCount - 1, M, ID, res, LN, RN, N; + + while (1) + { + M = (L + R)/2; + ID = ResStrOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + res = stricmp(ResStrName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ResStrOffsets[LN].NamId; + p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + res = stricmp(ResStrName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ResStrCount; RN++) + { + ID = ResStrOffsets[RN].NamId; + p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + res = stricmp(ResStrName, p + 4); + if (res) break; + } + for (N = LN + 1; N < RN; N++) + { + ID = ResStrOffsets[N].NamId; + p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); + ModID = *((WORD*)p); + for (n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) return N; + } + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +//Return proc index by name in given ModuleID +int __fastcall MKnowledgeBase::GetProcIdx(WORD ModuleID, char* ProcName) +{ + if (!Inited) return -1; + + if (ModuleID == 0xFFFF || !ProcName || !*ProcName || !ProcCount) return -1; + + WORD ModID; + int L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + int res = stricmp(ProcName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + for (int N = LN + 1; N < RN; N++) + { + ID = ProcOffsets[N].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModuleID == ModID) return N; + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +//Return proc index by name in given ModuleID +//Code used for selection required proc (if there are exist several procs with the same name) +int __fastcall MKnowledgeBase::GetProcIdx(WORD ModuleID, char* ProcName, BYTE* code) +{ + if (!Inited) return -1; + + if (ModuleID == 0xFFFF || !ProcName || !*ProcName || !ProcCount) return -1; + + MProcInfo aInfo; MProcInfo* pInfo; + WORD ModID; + int L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + int res = stricmp(ProcName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + for (int N = LN + 1; N < RN; N++) + { + pInfo = GetProcInfo(ProcOffsets[N].NamId, INFO_DUMP, &aInfo); + ModID = pInfo->ModuleID; + bool match = MatchCode(code, pInfo); + if (match && ModuleID == ModID) return N; + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +//Return proc index by name in given array of ModuleID +int __fastcall MKnowledgeBase::GetProcIdx(WORD* ModuleIDs, char* ProcName, BYTE* code) +{ + if (!Inited) return -1; + + if (!ModuleIDs || !ProcName || !*ProcName || !ProcCount) return -1; + + MProcInfo aInfo; MProcInfo* pInfo; + WORD ModuleID, ModID; + int n, L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + int res = stricmp(ProcName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + for (int N = LN + 1; N < RN; N++) + { + pInfo = GetProcInfo(ProcOffsets[N].NamId, INFO_DUMP, &aInfo); + ModID = pInfo->ModuleID; + if (code) + { + bool match = MatchCode(code, pInfo); + if (match) + { + for (n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) return N; + } + } + } + else + { + for (n = 0;;n++) + { + ModuleID = ModuleIDs[n]; + if (ModuleID == 0xFFFF) break; + if (ModuleID == ModID) return N; + } + } + } + //Nothing found - exit + return -1; + } + if (L > R) return -1; + } +} +//--------------------------------------------------------------------------- +//Seek first ans last proc ID in given module +bool __fastcall MKnowledgeBase::GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx) +{ + if (!Inited) return false; + + if (ModuleID == 0xFFFF || !ProcCount || !FirstProcIdx || !LastProcIdx) return false; + + *FirstProcIdx = -1; *LastProcIdx = -1; + WORD ModID; + int L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].ModId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + + if (ModuleID < ModID) + R = M - 1; + else if (ModuleID > ModID) + L = M + 1; + else + { + *FirstProcIdx = M; *LastProcIdx = M; + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].ModId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModID != ModuleID) break; + *FirstProcIdx = LN; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].ModId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModID != ModuleID) break; + *LastProcIdx = RN; + } + return true; + } + if (L > R) return false; + } +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx, int* DumpSize) +{ + if (!Inited || ModuleID == 0xFFFF || !ProcCount) return false; + + *FirstProcIdx = -1; *LastProcIdx = -1; *DumpSize = 0; + WORD ModID; + int L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].ModId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + + if (ModuleID < ModID) + R = M - 1; + else if (ModuleID > ModID) + L = M + 1; + else + { + *FirstProcIdx = M; *LastProcIdx = M; + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].ModId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModID != ModuleID) break; + *FirstProcIdx = LN; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].ModId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + ModID = *((WORD*)p); + if (ModID != ModuleID) break; + *LastProcIdx = RN; + } + for (int m = *FirstProcIdx; m <= *LastProcIdx; m++) + { + p = GetKBCachePtr(ProcOffsets[m].Offset, ProcOffsets[m].Size); + //ModuleID + p += 2; + //ProcName + WORD Len = *((WORD*)p); p += Len + 3; + //Embedded + p++; + //DumpType + p++; + //MethodKind + p++; + //CallKind + p++; + //VProc + p += 4; + //TypeDef + Len = *((WORD*)p); p += Len + 3; + //DumpTotal + p += 4; + //DumpSz + int size = *((DWORD*)p); + *DumpSize += (size + 3) & (-4); + } + return true; + } + if (L > R) return false; + } +} +//--------------------------------------------------------------------------- +//ConstIdx was given by const name +MConstInfo* __fastcall MKnowledgeBase::GetConstInfo(int AConstIdx, DWORD AFlags, MConstInfo* cInfo) +{ + if (!Inited) return 0; + + if (AConstIdx == -1) return 0; + + const BYTE* p = GetKBCachePtr(ConstOffsets[AConstIdx].Offset, ConstOffsets[AConstIdx].Size); + cInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + cInfo->ConstName = String((char*)p); p += Len + 1; + cInfo->Type = *p; p++; + Len = *((WORD*)p); p += 2; + cInfo->TypeDef = String((char*)p); p += Len + 1; + Len = *((WORD*)p); p += 2; + cInfo->Value = String((char*)p); p += Len + 1; + + DWORD DumpTotal = *((DWORD*)p); p += 4; + cInfo->DumpSz = *((DWORD*)p); p += 4; + cInfo->FixupNum = *((DWORD*)p); p += 4; + cInfo->Dump = 0; + + if (AFlags & INFO_DUMP) + { + if (cInfo->DumpSz) cInfo->Dump = (BYTE*)p; + } + return cInfo; +} +//--------------------------------------------------------------------------- +MProcInfo* __fastcall MKnowledgeBase::GetProcInfo(char* ProcName, DWORD AFlags, MProcInfo *pInfo, int *procIdx) +{ + if (!Inited) return 0; + + if (!ProcName || !*ProcName || !ProcCount) return 0; + + WORD ModID; + int L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + int res = stricmp(ProcName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + int LN, RN; + //Find left boundary + for (LN = M - 1; LN >= 0; LN--) + { + ID = ProcOffsets[LN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + //Find right boundary + for (RN = M + 1; RN < ProcCount; RN++) + { + ID = ProcOffsets[RN].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + } + if (RN - LN - 1 == 1) + { + ID = ProcOffsets[M].NamId; + *procIdx = ID; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + + pInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + pInfo->ProcName = String((char*)p); p += Len + 1; + pInfo->Embedded = *p; p++; + pInfo->DumpType = *p; p++; + pInfo->MethodKind = *p; p++; + pInfo->CallKind = *p; p++; + pInfo->VProc = *((int*)p); p += 4; + Len = *((WORD*)p); p += 2; + pInfo->TypeDef = TrimTypeName(String((char*)p)); p += Len + 1; + + DWORD DumpTotal = *((DWORD*)p); p += 4; + const BYTE *p1 = p; + pInfo->DumpSz = *((DWORD*)p); p += 4; + pInfo->FixupNum = *((DWORD*)p); p += 4; + pInfo->Dump = 0; + + if (AFlags & INFO_DUMP) + { + if (pInfo->DumpSz) pInfo->Dump = (BYTE*)p; + } + p = p1 + DumpTotal; + + DWORD ArgsTotal = *((DWORD*)p); p += 4; + p1 = p; + pInfo->ArgsNum = *((WORD*)p); p += 2; + pInfo->Args = 0; + + if (AFlags & INFO_ARGS) + { + if (pInfo->ArgsNum) pInfo->Args = (BYTE*)p; + } + p = p1 + ArgsTotal; + /* + DWORD LocalsTotal = *((DWORD*)p); p += 4; + pInfo->LocalsNum = *((WORD*)p); p += 2; + pInfo->Locals = 0; + + if (AFlags & INFO_LOCALS) + { + if (pInfo->LocalsNum) pInfo->Locals = (BYTE*)p; + } + */ + return pInfo; + } + //More than 2 items found + /* + for (int nnn = LN + 1; nnn <= RN - 1; nnn++) + { + ID = ProcOffsets[nnn].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + + pInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + pInfo->ProcName = String((char*)p); p += Len + 1; + pInfo->Embedded = *p; p++; + pInfo->DumpType = *p; p++; + pInfo->MethodKind = *p; p++; + pInfo->CallKind = *p; p++; + pInfo->VProc = *((int*)p); p += 4; + Len = *((WORD*)p); p += 2; + pInfo->TypeDef = TrimTypeName(String((char*)p)); p += Len + 1; + + DWORD DumpTotal = *((DWORD*)p); p += 4; + const BYTE *p1 = p; + pInfo->DumpSz = *((DWORD*)p); p += 4; + pInfo->FixupNum = *((DWORD*)p); p += 4; + pInfo->Dump = 0; + + if (AFlags & INFO_DUMP) + { + if (pInfo->DumpSz) pInfo->Dump = (BYTE*)p; + } + p = p1 + DumpTotal; + + DWORD ArgsTotal = *((DWORD*)p); p += 4; + p1 = p; + pInfo->ArgsNum = *((WORD*)p); p += 2; + pInfo->Args = 0; + + if (AFlags & INFO_ARGS) + { + if (pInfo->ArgsNum) pInfo->Args = (BYTE*)p; + } + } + */ + return (MProcInfo*)-1; + } + if (L > R) return 0; + } +} +//--------------------------------------------------------------------------- +MProcInfo* __fastcall MKnowledgeBase::GetProcInfo(int AProcIdx, DWORD AFlags, MProcInfo *pInfo) +{ + if (!Inited) return 0; + + if (AProcIdx == -1) return 0; + + const BYTE *p = GetKBCachePtr(ProcOffsets[AProcIdx].Offset, ProcOffsets[AProcIdx].Size); + + pInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + pInfo->ProcName = String((char*)p); p += Len + 1; + pInfo->Embedded = *p; p++; + pInfo->DumpType = *p; p++; + pInfo->MethodKind = *p; p++; + pInfo->CallKind = *p; p++; + pInfo->VProc = *((int*)p); p += 4; + Len = *((WORD*)p); p += 2; + pInfo->TypeDef = TrimTypeName(String((char*)p)); p += Len + 1; + + DWORD DumpTotal = *((DWORD*)p); p += 4; + const BYTE *p1 = p; + pInfo->DumpSz = *((DWORD*)p); p += 4; + pInfo->FixupNum = *((DWORD*)p); p += 4; + pInfo->Dump = 0; + + if (AFlags & INFO_DUMP) + { + if (pInfo->DumpSz) pInfo->Dump = (BYTE*)p; + } + p = p1 + DumpTotal; + + DWORD ArgsTotal = *((DWORD*)p); p += 4; + p1 = p; + pInfo->ArgsNum = *((WORD*)p); p += 2; + pInfo->Args = 0; + + if (AFlags & INFO_ARGS) + { + if (pInfo->ArgsNum) pInfo->Args = (BYTE*)p; + } + p = p1 + ArgsTotal; + /* + DWORD LocalsTotal = *((DWORD*)p); p += 4; + pInfo->LocalsNum = *((WORD*)p); p += 2; + pInfo->Locals = 0; + + if (AFlags & INFO_LOCALS) + { + if (pInfo->LocalsNum) pInfo->Locals = (BYTE*)p; + } + */ + return pInfo; +} +//--------------------------------------------------------------------------- +MTypeInfo* __fastcall MKnowledgeBase::GetTypeInfo(int ATypeIdx, DWORD AFlags, MTypeInfo *tInfo) +{ + if (!Inited) return 0; + + if (ATypeIdx == -1) return 0; + + const BYTE* p = GetKBCachePtr(TypeOffsets[ATypeIdx].Offset, TypeOffsets[ATypeIdx].Size); + + //Modified by ZGL + if (Version == 1) + tInfo->Size = TypeOffsets[ATypeIdx].Size; + else + tInfo->Size = *((DWORD*)p); p += 4; + + tInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + tInfo->TypeName = String((char*)p); p += Len + 1; + tInfo->Kind = *p; p++; + tInfo->VMCnt = *((WORD*)p); p += 2; + Len = *((WORD*)p); p += 2; + tInfo->Decl = String((char*)p); p += Len + 1; + + DWORD DumpTotal = *((DWORD*)p); p += 4; + BYTE *p1 = (BYTE*)p; + tInfo->DumpSz = *((DWORD*)p); p += 4; + tInfo->FixupNum = *((DWORD*)p); p += 4; + tInfo->Dump = 0; + + if (AFlags & INFO_DUMP) + { + if (tInfo->DumpSz) tInfo->Dump = (BYTE*)p; + } + p = p1 + DumpTotal; + + DWORD FieldsTotal = *((DWORD*)p); p += 4; + p1 = (BYTE*)p; + tInfo->FieldsNum = *((WORD*)p); p += 2; + tInfo->Fields = 0; + + if (AFlags & INFO_FIELDS) + { + if (tInfo->FieldsNum) tInfo->Fields = (BYTE*)p; + } + p = p1 + FieldsTotal; + + DWORD PropsTotal = *((DWORD*)p); p += 4; + p1 = (BYTE*)p; + tInfo->PropsNum = *((WORD*)p); p += 2; + tInfo->Props = 0; + + if (AFlags & INFO_PROPS) + { + if (tInfo->PropsNum) tInfo->Props = (BYTE*)p; + } + p = p1 + PropsTotal; + + DWORD MethodsTotal = *((DWORD*)p); p += 4; + tInfo->MethodsNum = *((WORD*)p); p += 2; + tInfo->Methods = 0; + + if (AFlags & INFO_METHODS) + { + if (tInfo->MethodsNum) tInfo->Methods = (BYTE*)p; + } + return tInfo; +} +//--------------------------------------------------------------------------- +MVarInfo* __fastcall MKnowledgeBase::GetVarInfo(int AVarIdx, DWORD AFlags, MVarInfo* vInfo) +{ + if (!Inited) return 0; + + if (AVarIdx == -1) return 0; + + const BYTE* p = GetKBCachePtr(VarOffsets[AVarIdx].Offset, VarOffsets[AVarIdx].Size); + + vInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + vInfo->VarName = String((char*)p); p += Len + 1; + vInfo->Type = *p; p++; + Len = *((WORD*)p); p += 2; + vInfo->TypeDef = String((char*)p); p += Len + 1; + + if (AFlags & INFO_ABSNAME) + { + Len = *((WORD*)p); p += 2; + vInfo->AbsName = String((char*)p); + } + + return vInfo; +} +//--------------------------------------------------------------------------- +MResStrInfo* __fastcall MKnowledgeBase::GetResStrInfo(int AResStrIdx, DWORD AFlags, MResStrInfo* rsInfo) +{ + if (!Inited) return 0; + + if (AResStrIdx == -1) return 0; + + const BYTE* p = GetKBCachePtr(ResStrOffsets[AResStrIdx].Offset, ResStrOffsets[AResStrIdx].Size); + + rsInfo->ModuleID = *((WORD*)p); p += 2; + WORD Len = *((WORD*)p); p += 2; + rsInfo->ResStrName = String((char*)p); p += Len + 1; + Len = *((WORD*)p); p += 2; + rsInfo->TypeDef = String((char*)p); p += Len + 1; + + if (AFlags & INFO_DUMP) + { + //Len = *((WORD*)p); p += 2; + //rsInfo->AContext = String((char*)p); + } + + return rsInfo; +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::ScanCode(BYTE* code, DWORD* CodeFlags, DWORD CodeSz, MProcInfo* pInfo) +{ + if (!Inited) return -1; + + if (!pInfo) return -1; + + DWORD DumpSz = pInfo->DumpSz; + if (!DumpSz || DumpSz >= CodeSz) return -1; + BYTE* Dump = pInfo->Dump; + BYTE* Relocs = Dump + DumpSz; + int i, n; + + //Skip relocs in dump begin + for (n = 0; n < DumpSz; n++) + { + if (Relocs[n] != 0xFF) break; + } + for (int i = n; i < CodeSz - DumpSz + n; i++) + { + if (code[i] == Dump[n] && (CodeFlags[i] & cfCode) == 0 && (CodeFlags[i] & cfData) == 0) + { + bool found = true; + for (int k = n; k < DumpSz; k++) + { + if ((CodeFlags[i - n + k] & cfCode) != 0 || (CodeFlags[i - n + k] & cfData) != 0) + { + found = false; + break; + } + if (code[i - n + k] != Dump[k] && Relocs[k] != 0xFF) + { + found = false; + break; + } + } + if (found) + { + //If "tail" matched (from position i - n), check "head" + found = true; + for (int k = 0; k < n; k++) + { + if ((CodeFlags[i - n + k] & cfCode) != 0 || (CodeFlags[i - n + k] & cfData) != 0) + { + found = false; + break; + } + } + if (found) + return i - n; + } + } + } + return -1; +} +//--------------------------------------------------------------------------- +//Fill used modules ids array + module itself +WORD* __fastcall MKnowledgeBase::GetModuleUses(WORD ModuleID) +{ + if (!Inited) return 0; + + if (ModuleID == 0xFFFF) return 0; + + const BYTE* p = GetKBCachePtr(ModuleOffsets[ModuleID].Offset, ModuleOffsets[ModuleID].Size); + + //ID + p += 2; + //Name + WORD len = *((WORD*)p); p += len + 3; + //Filename + len = *((WORD*)p); p += len + 3; + //UsesNum + WORD UsesNum = *((WORD*)p); + WORD *uses = new WORD[UsesNum + 2]; + uses[0] = ModuleID; + int m = 1; + if (UsesNum) + { + p += 2; + for (int n = 0; n < UsesNum; n++) + { + WORD ID = *((WORD*)p); p += 2; + if (ID != 0xFFFF) + { + uses[m] = ID; + m++; + } + } + } + uses[m] = 0xFFFF; + return uses; +} +//--------------------------------------------------------------------------- +int __fastcall MKnowledgeBase::GetProcUses(char* ProcName, WORD* uses) +{ + if (!Inited) return 0; + + int num = 0; + + int L = 0, R = ProcCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = ProcOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + + int res = stricmp(ProcName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + WORD ModID = *((WORD*)p); + if (ModID != 0xFFFF) + { + uses[num] = ModID; + num++; + } + //Take ModuleIDs in same name block (firstly from right to left) + for (int N = M - 1; N >= 0; N--) + { + ID = ProcOffsets[N].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + ModID = *((WORD*)p); + if (ModID != 0xFFFF && uses[num - 1] != ModID) + { + uses[num] = ModID; + num++; + assert(num < ModuleCount); + } + } + //From ltft to right + for (int N = M + 1; N < ProcCount; N++) + { + ID = ProcOffsets[N].NamId; + p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); + res = stricmp(ProcName, p + 4); + if (res) break; + ModID = *((WORD*)p); + if (ModID != 0xFFFF && uses[num - 1] != ModID) + { + uses[num] = ModID; + num++; + assert(num < ModuleCount); + } + } + return num; + } + if (L > R) return 0; + } +} +//--------------------------------------------------------------------------- +WORD* __fastcall MKnowledgeBase::GetTypeUses(char* TypeName) +{ + if (!Inited) return 0; + + int num = 0; + WORD *uses = 0; + + int L = 0, R = TypeCount - 1; + while (1) + { + int M = (L + R)/2; + int ID = TypeOffsets[M].NamId; + const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + + int res = stricmp(TypeName, p + 4); + if (res < 0) + R = M - 1; + else if (res > 0) + L = M + 1; + else + { + uses = new WORD[ModuleCount + 1]; + WORD ModID = *((WORD*)p); + if (ModID != 0xFFFF) + { + uses[num] = ModID; + num++; + } + //Take ModuleIDs in same name block (firstly from right to left) + for (int N = M - 1; N >= 0; N--) + { + ID = TypeOffsets[N].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + res = stricmp(TypeName, p + 4); + if (res) break; + ModID = *((WORD*)p); + if (ModID != 0xFFFF && uses[num - 1] != ModID) + { + uses[num] = ModID; + num++; + assert(num < ModuleCount); + } + } + //From left to right + for (int N = M + 1; N < TypeCount; N++) + { + ID = TypeOffsets[N].NamId; + p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size);// + 4; + if (Version >= 2) p += 4; //Add by ZGL + res = stricmp(TypeName, p + 4); + if (res) break; + ModID = *((WORD*)p); + if (ModID != 0xFFFF && uses[num - 1] != ModID) + { + uses[num] = ModID; + num++; + assert(num < ModuleCount); + } + } + //After last element must be word 0xFFFF + uses[num] = 0xFFFF; + return uses; + } + if (L > R) return 0; + } +} +//--------------------------------------------------------------------------- +WORD* __fastcall MKnowledgeBase::GetConstUses(char* ConstName) +{ + if (!Inited) return 0; + + int ID, num; + WORD ModID, *uses = 0; + const BYTE *p; + + int F = 0, L = ConstCount - 1; + while (F < L) + { + int M = (F + L)/2; + ID = ConstOffsets[M].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + if (stricmp(ConstName, p + 4) <= 0) + L = M; + else + F = M + 1; + } + ID = ConstOffsets[L].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + if (!stricmp(ConstName, p + 4)) + { + uses = new WORD[ModuleCount + 1]; num = 0; + ModID = *((WORD*)p); + if (ModID != 0xFFFF) + { + uses[num] = ModID; + num++; + } + //Take ModuleIDs in same name block (firstly from right to left) + for (int N = L - 1; N >= 0; N--) + { + ID = ConstOffsets[N].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + if (stricmp(ConstName, p + 4)) break; + ModID = *((WORD*)p); + if (ModID != 0xFFFF && uses[num - 1] != ModID) + { + uses[num] = ModID; + num++; + assert(num < ModuleCount); + } + } + //From left to right + for (int N = L + 1; N < ConstCount; N++) + { + ID = ConstOffsets[N].NamId; + p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); + if (stricmp(ConstName, p + 4)) break; + ModID = *((WORD*)p); + if (ModID != 0xFFFF && uses[num - 1] != ModID) + { + uses[num] = ModID; + num++; + assert(num < ModuleCount); + } + } + //After last element must be word 0xFFFF + uses[num] = 0xFFFF; + return uses; + } + return 0; +} +//--------------------------------------------------------------------------- +String __fastcall MKnowledgeBase::GetProcPrototype(int ProcIdx) +{ + MProcInfo pInfo; + if (Inited && GetProcInfo(ProcIdx, INFO_ARGS, &pInfo)) return GetProcPrototype(&pInfo); + return ""; +} +//--------------------------------------------------------------------------- +String __fastcall MKnowledgeBase::GetProcPrototype(MProcInfo* pInfo) +{ + String Result = ""; + + if (pInfo) + { + switch (pInfo->MethodKind) + { + case 'C': + Result += "constructor"; + break; + case 'D': + Result += "destructor"; + break; + case 'F': + Result += "function"; + break; + case 'P': + Result += "procedure"; + break; + } + if (Result != "") Result += " "; + Result += pInfo->ProcName; + + if (pInfo->ArgsNum) Result += "("; + + BYTE *p = pInfo->Args; WORD Len; + for (int n = 0; n < pInfo->ArgsNum; n++) + { + if (n) Result += "; "; + //Tag + if (*p == 0x22) Result += "var "; p++; + //Register + p += 4; + //Ndx + p += 4; + //Name + Len = *((WORD*)p); p += 2; + Result += String((char*)p, Len) + ":"; p += Len + 1; + //TypeDef + Len = *((WORD*)p); p += 2; + Result += String((char*)p, Len); p += Len + 1; + } + if (pInfo->ArgsNum) Result += ")"; + if (pInfo->MethodKind == 'F') + { + Result += ":" + pInfo->TypeDef; + } + Result += ";"; + if (pInfo->CallKind) Result += " "; + switch (pInfo->CallKind) + { + case 1: + Result += "cdecl"; + break; + case 2: + Result += "pascal"; + break; + case 3: + Result += "stdcall"; + break; + case 4: + Result += "safecall"; + break; + } + if (pInfo->CallKind) Result += ";"; + } + return Result; +} +//--------------------------------------------------------------------------- +//as +//return direct pointer to const data of KB +const BYTE* __fastcall MKnowledgeBase::GetKBCachePtr(DWORD Offset, DWORD Size) +{ + assert(Offset >= 0 && Offset < SizeKBFile && (Offset + Size < SizeKBFile)); + return KBCache + Offset; +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::IsUsedProc(int AIdx) +{ + return (UsedProcs[AIdx] == 1); +} +//--------------------------------------------------------------------------- +void __fastcall MKnowledgeBase::SetUsedProc(int AIdx) +{ + UsedProcs[AIdx] = 1; +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::GetKBProcInfo(String typeName, MProcInfo* procInfo, int* procIdx) +{ + int res, idx; + + res = (int)GetProcInfo(typeName.c_str(), INFO_DUMP | INFO_ARGS, procInfo, procIdx); + if (res && res != -1) + { + return true; + } + return false; +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::GetKBTypeInfo(String typeName, MTypeInfo* typeInfo) +{ + int idx; + WORD *uses; + + uses = GetTypeUses(typeName.c_str()); + idx = GetTypeIdxByModuleIds(uses, typeName.c_str()); + if (uses) delete[] uses; + if (idx != -1) + { + idx = TypeOffsets[idx].NamId; + if (GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS /*| INFO_DUMP*/, typeInfo)) + { + return true; + } + } + return false; +} +//--------------------------------------------------------------------------- +bool __fastcall MKnowledgeBase::GetKBPropertyInfo(String className, String propName, MTypeInfo* typeInfo) +{ + int n, idx, pos; + BYTE *p; + WORD *uses, Len; + MTypeInfo tInfo; + String name, type; + + uses = GetTypeUses(className.c_str()); + idx = GetTypeIdxByModuleIds(uses, className.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = TypeOffsets[idx].NamId; + if (GetTypeInfo(idx, INFO_PROPS, &tInfo)) + { + p = tInfo.Props; + for (n = 0; n < tInfo.PropsNum; n++) + { + p++;//Scope + p += 4;//Index + p += 4;//DispID + Len = *((WORD*)p); p += 2; + name = String((char*)p, Len); p += Len + 1;//Name + Len = *((WORD*)p); p += 2; + type = TrimTypeName(String((char*)p, Len)); p += Len + 1;//TypeDef + Len = *((WORD*)p); p += 2 + Len + 1;//ReadName + Len = *((WORD*)p); p += 2 + Len + 1;//WriteName + Len = *((WORD*)p); p += 2 + Len + 1;//StoredName + + if (SameText(name, propName)) + { + pos = type.LastDelimiter(":."); + if (pos) type = type.SubString(pos + 1, type.Length()); + return GetKBTypeInfo(type, typeInfo); + } + } + } + } + return false; +} +//--------------------------------------------------------------------------- +String __fastcall MKnowledgeBase::IsPropFunction(String className, String procName) +{ + int n, idx; + BYTE *p; + WORD *uses, Len; + MTypeInfo tInfo; + String pname, type, fname; + + uses = GetTypeUses(className.c_str()); + idx = GetTypeIdxByModuleIds(uses, className.c_str()); + if (uses) delete[] uses; + if (idx != -1) + { + idx = TypeOffsets[idx].NamId; + if (GetTypeInfo(idx, INFO_PROPS, &tInfo)) + { + p = tInfo.Props; + for (n = 0; n < tInfo.PropsNum; n++) + { + p++;//Scope + p += 4;//Index + p += 4;//DispID + Len = *((WORD*)p); p += 2; + pname = String((char*)p, Len); p += Len + 1;//Name + Len = *((WORD*)p); p += 2; + type = TrimTypeName(String((char*)p, Len)); p += Len + 1;//TypeDef + Len = *((WORD*)p); p += 2; + fname = TrimTypeName(String((char*)p, Len)); p += Len + 1;//ReadName + if (SameText(procName, fname)) + return pname; + Len = *((WORD*)p); p += 2; + fname = TrimTypeName(String((char*)p, Len)); p += Len + 1;//WriteName + if (SameText(procName, fname)) + return pname; + Len = *((WORD*)p); p += 2; + fname = TrimTypeName(String((char*)p, Len)); p += Len + 1;//StoredName + if (SameText(procName, fname)) + return pname; + } + } + } + return ""; +} +//--------------------------------------------------------------------------- + diff --git a/KnowledgeBase.h b/KnowledgeBase.h new file mode 100644 index 0000000..904ad68 --- /dev/null +++ b/KnowledgeBase.h @@ -0,0 +1,390 @@ +//--------------------------------------------------------------------------- +#ifndef KnowledgeBaseH +#define KnowledgeBaseH +//--------------------------------------------------------------------------- +#include +//--------------------------------------------------------------------------- +//Èíôîðìàöèÿ î ñìåùåíèÿõ èìåí è äàííûõ +typedef struct +{ + DWORD Offset; + DWORD Size; + int ModId; //Modules + int NamId; //Names +} OFFSETSINFO, *POFFSETSINFO; +//Fixup info +typedef struct +{ + BYTE Type; //'A' - ADR, 'J' - JMP, 'D' - DAT + DWORD Ofs; //Ñìåùåíèå îòíîñèòåëüíî íà÷àëà äàìïà + char *Name; +} FIXUPINFO, *PFIXUPINFO; + +/* +ModuleDataTable +--------------- +//Ñîñòîèò èç ModuleCount çàïèñåé âèäà +WORD ID; +PSTR ModuleName; +PSTR Filename; +WORD UsesNum; +WORD UsesID[UsesNum]; //Ìàññèâ èäåíòèôèêàòîðîâ ìîäóëåé +PSTR UsesNames[UsesNum]; //Ìàññèâ èìåí ìîäóëåé + +ConstDataTable +-------------- +//Ñîñòîèò èç ModuleCount çàïèñåé âèäà +WORD ModuleID; +PSTR ConstName; +BYTE Type; //'C'-ConstDecl, 'P'-PDecl (VMT), 'V'-VarCDecl +PSTR TypeDef; //Òèï +PSTR Value; //Çíà÷åíèå +DWORD DumpTotal; //Îáùèé ðàçìåð äàìïà (äàìï+ðåëîêè+ôèêñàïû) +DWORD DumpSize; //Ðàçìåð áèíàðíîãî äàìïà (RTTI) +DWORD FixupNum; //Êîëè÷åñòâî ôèêñàïîâ äàìïà +BYTE Dump[DumpSize]; //Áèíàðíûé äàìï (RTTI) +BYTE Relocs[DumpSize]; +FIXUPINFO Fixups[FixupNum]; //Ìàññèâ ôèêñàïîâ + +TypeDataTable +------------- +//Ñîñòîèò èç TypeCount çàïèñåé âèäà +DWORD Size; //Size of Type +WORD ModuleID; +PSTR TypeName; +BYTE Kind; //drArrayDef,...,drVariantDef (ñì. íà÷àëî) +DWORD VMCnt; //Êîëè÷åñòâî ýëåìåíòîâ VMT (íà÷èíàÿ ñ 0) +PSTR Decl; //Äåêëàðàöèÿ +DWORD DumpTotal; //Îáùèé ðàçìåð äàìïà (äàìï+ðåëîêè+ôèêñàïû) +DWORD DumpSize; //Ðàçìåð áèíàðíîãî äàìïà (RTTI) +DWORD FixupNum; //Êîëè÷åñòâî ôèêñàïîâ äàìïà +BYTE Dump[DumpSize]; //Áèíàðíûé äàìï (RTTI) +BYTE Relocs[DumpSize]; +FIXUPINFO Fixups[FixupNum]; //Ôèêñàïû +DWORD FieldsTotal; //Îáùèé ðàçìåð äàííûõ ïîëåé +WORD FieldsNum; //Êîëè÷åñòâî ïîëåé (class, interface, record) +FIELDINFO Fields[FieldNum]; //Ïîëÿ +DWORD PropsTotal; //Îáùèé ðàçìåð äàííûõ ñâîéñòâ +WORD PropsNum; //Êîëè÷åñòâî ñâîéñòâ (class, interface) +PROPERTYINFO Props[PropNum]; //Ñâîéñòâà +DWORD MethodsTotal; //Îáùèé ðàçìåð äàííûõ ìåòîäîâ +WORD MethodsNum; //Êîëè÷åñòâî ìåòîäîâ (class, interface) +METHODINFO Methods[MethodNum]; //Ìåòîäû + +VarDataTable +------------ +//Ñîñòîèò èç VarCount çàïèñåé âèäà +WORD ModuleID; +PSTR VarName; +BYTE Type; //'V'-Var;'A'-AbsVar;'S'-SpecVar;'T'-ThreadVar +PSTR TypeDef; +PSTR AbsName; //Äëÿ êëþ÷åâîãî ñëîâà absolute + +ResStrDataTable +--------------- +//Ñîñòîèò èç ResStrCount çàïèñåé âèäà +WORD ModuleID; +PSTR ResStrName; +PSTR TypeDef; +PSTR Context; + +ProcDataTable +------------- +//Contains ProcCount structures: +WORD ModuleID; +PSTR ProcName; +BYTE Embedded; //Contains embedded procs +BYTE DumpType; //'C' - code, 'D' - data +BYTE MethodKind; //'M'-method,'P'-procedure,'F'-function,'C'-constructor,'D'-destructor +BYTE CallKind; //1-'cdecl', 2-'pascal', 3-'stdcall', 4-'safecall' +int VProc; //Flag for "overload" (if Delphi version > verD3 and VProc&0x1000 != 0) +PSTR TypeDef; //Type of Result for function +DWORD DumpTotal; //Total size of dump (dump+relocs+fixups) +DWORD DumpSz; //Dump size +DWORD FixupNum; //Dump fixups number +BYTE Dump[DumpSz]; //Binary dump +BYTE Relocs[DumpSize]; +FIXUPINFO Fixups[FixupNum]; //Fixups +DWORD ArgsTotal; //Total size of arguments +WORD ArgsNum; //Arguments number +ARGINFO Args[ArgNum]; //Arguments +DWORD LocalsTotal; //Total size of local vars +WORD LocalsNum; //Local vars number +LOCALINFO Locals[LocalNum]; //Local vars +*/ + +#define SCOPE_TMP 32 //Temp struct FIELDINFO, to be deleted +typedef struct FIELDINFO +{ + FIELDINFO():xrefs(0){} + ~FIELDINFO(); + BYTE Scope; //9-private, 10-protected, 11-public, 12-published + int Offset; //Offset in class instance + int Case; //Case for record (in other cases 0xFFFFFFFF) + String Name; //Field Name + String Type; //Field Type + TList *xrefs; //Xrefs from code +} FIELDINFO, *PFIELDINFO; + +typedef struct +{ + BYTE Scope; //9-private, 10-protected, 11-public, 12-published + int Index; //readonly, writeonly â çàâèñèìîñòè îò óñòàíîâêè áèò 1 è 2 + int DispID; //??? + String Name; //Èìÿ ñâîéñòâà + String TypeDef; //Òèï ñâîéñòâà + String ReadName; //Ïðîöåäóðà äëÿ ÷òåíèÿ ñâîéñòâà èëè ñîîòâåòñòâóþùåå ïîëå + String WriteName; //Ïðîöåäóðà äëÿ çàïèñè ñâîéñòâà èëè ñîîòâåòñòâóþùåå ïîëå + String StoredName; //Ïðîöåäóðà äëÿ ïðîâåðêè ñâîéñòâà èëè ñîîòâåòñòâóþùåå çíà÷åíèå +} PROPINFO, *PPROPINFO; + +typedef struct +{ + BYTE Scope; //9-private, 10-protected, 11-public, 12-published + BYTE MethodKind; //'M'-method, 'P'-procedure, 'F'-function, 'C'-constructor, 'D'-destructor + String Prototype; //Prototype full name +} METHODINFO, *PMETHODINFO; + +typedef struct +{ + BYTE Tag; //0x21-"val", 0x22-"var" + bool Register; //If true - argument is in register, else - in stack + int Ndx; //Register number and offset (XX-number, XXXXXX-offset) (0-EAX, 1-ECX, 2-EDX) + int Size; //Argument Size + String Name; //Argument Name + String TypeDef; //Argument Type +} ARGINFO, *PARGINFO; + +typedef struct +{ + int Ofs; //Offset of local var (from ebp or EP) + int Size; //Size of local var + String Name; //Local var Name + String TypeDef; //Local var Type +} LOCALINFO, *PLOCALINFO; + +typedef struct +{ + char type; //'C'-call; 'J'-jmp; 'D'-data + DWORD adr; //address of procedure + int offset; //offset in procedure +} XrefRec, *PXrefRec; + + +//Ôëàæêè äëÿ çàïîëíåíèÿ ÷ëåíîâ êëàññîâ +#define INFO_DUMP 1 +#define INFO_ARGS 2 +#define INFO_LOCALS 4 +#define INFO_FIELDS 8 +#define INFO_PROPS 16 +#define INFO_METHODS 32 +#define INFO_ABSNAME 64 + +class MConstInfo +{ +public: + __fastcall MConstInfo(); + __fastcall ~MConstInfo(); +public: + WORD ModuleID; + String ConstName; + BYTE Type; //'C'-ConstDecl, 'P'-PDecl (VMT), 'V'-VarCDecl + String TypeDef; //Òèï + String Value; //Çíà÷åíèå + DWORD DumpSz; //Ðàçìåð áèíàðíîãî äàìïà + DWORD FixupNum; //Êîëè÷åñòâî ôèêñàïîâ äàìïà + BYTE *Dump; //Áèíàðíûé äàìï +}; + +//Çíà÷åíèÿ áàéòà Kind èíôîðìàöèè î òèïå +#define drArrayDef 0x4C //'L' +#define drClassDef 0x46 //'F' +#define drFileDef 0x4F //'O' +#define drFloatDef 0x49 //'I' +#define drInterfaceDef 0x54 //'T' +#define drObjVMTDef 0x47 //'G' +#define drProcTypeDef 0x48 //'H' +#define drPtrDef 0x45 //'E' +#define drRangeDef 0x44 //'D' +#define drRecDef 0x4D //'M' +#define drSetDef 0x4A //'J' +#define drShortStrDef 0x4B //'K' +#define drStringDef 0x52 //'R' +#define drTextDef 0x50 //'P' +#define drVariantDef 0x53 //'S' +#define drAliasDef 0x41 //'Z' + +class MTypeInfo +{ +public: + __fastcall MTypeInfo(); + __fastcall ~MTypeInfo(); +public: + DWORD Size; + WORD ModuleID; + String TypeName; + BYTE Kind; //drArrayDef,...,drVariantDef + WORD VMCnt; //VMT elements number (from 0) + String Decl; //Declaration + DWORD DumpSz; //Binary dump size + DWORD FixupNum; //Binary dump fixup number + BYTE *Dump; //Binary dump + WORD FieldsNum; //Fields number (class, interface, record) + BYTE *Fields; + WORD PropsNum; //Properties number (class, interface) + BYTE *Props; + WORD MethodsNum; //Methods number (class, interface) + BYTE *Methods; +}; +//Var Type field +#define VT_VAR 'V' +#define VT_ABSVAR 'A' +#define VT_SPECVAR 'S' +#define VT_THREADVAR 'T' + +class MVarInfo +{ +public: + __fastcall MVarInfo(); + __fastcall ~MVarInfo(); +public: + WORD ModuleID; + String VarName; + BYTE Type; //'V'-Var;'A'-AbsVar;'S'-SpecVar;'T'-ThreadVar + String TypeDef; + String AbsName; //Äëÿ êëþ÷åâîãî ñëîâà absolute +}; + +class MResStrInfo +{ +public: + __fastcall MResStrInfo(); + __fastcall ~MResStrInfo(); +public: + WORD ModuleID; + String ResStrName; + String TypeDef; + //String Context; +}; + +class MProcInfo +{ +public: + __fastcall MProcInfo(); + __fastcall ~MProcInfo(); +public: + WORD ModuleID; + String ProcName; + bool Embedded; //true-ñîäåðæèò âëîæåííûå ïðîöåäóðû + char DumpType; //'C' - êîä, 'D' - äàííûå + char MethodKind; //'M'-method,'P'-procedure,'F'-function,'C'-constructor,'D'-destructor + BYTE CallKind; //1-'cdecl', 2-'pascal', 3-'stdcall', 4-'safecall' + int VProc; //ôëàæîê äëÿ "overload" (åñëè âåðñèÿ Äåëüôè > verD3 è VProc&0x1000 != 0) + String TypeDef; //Òèï + DWORD DumpSz; //Ðàçìåð áèíàðíîãî äàìïà + DWORD FixupNum; //Êîëè÷åñòâî ôèêñàïîâ äàìïà + BYTE *Dump; //Áèíàðíûé äàìï (âêëþ÷àåò â ñåáÿ ñîáñòâåííî äàìï, ðåëîêè è ôèêñàïû) + WORD ArgsNum; //Êîëè÷åñòâî àðãóìåíòîâ ïðîöåäóðû + BYTE *Args; //Ñïèñîê àðãóìåíòîâ + //WORD LocalsNum; //Êîëè÷åñòâî ëîêàëüíûõ ïåðåìåííûõ ïðîöåäóðû + //BYTE *Locals; //Ñïèñîê ëîêàëüíûõ ïåðåìåííûõ +}; +//Ñåêöèè áàçû çíàíèé +#define KB_NO_SECTION 0 +#define KB_CONST_SECTION 1 +#define KB_TYPE_SECTION 2 +#define KB_VAR_SECTION 4 +#define KB_RESSTR_SECTION 8 +#define KB_PROC_SECTION 16 + +class MKnowledgeBase +{ +public: + __fastcall MKnowledgeBase(); + __fastcall ~MKnowledgeBase(); + + bool __fastcall Open(char* filename); + void __fastcall Close(); + + const BYTE* __fastcall GetKBCachePtr(DWORD Offset, DWORD Size); + WORD __fastcall GetModuleID(char* ModuleName); + String __fastcall GetModuleName(WORD ModuleID); + void __fastcall GetModuleIdsByProcName(char* ProcName); + int __fastcall GetItemSection(WORD* ModuleIDs, char* ItemName); + int __fastcall GetConstIdx(WORD* ModuleID, char* ConstName); + int __fastcall GetConstIdxs(char* ConstName, int* ConstIdx); + int __fastcall GetTypeIdxByModuleIds(WORD* ModuleIDs, char* TypeName); + int __fastcall GetTypeIdxsByName(char* TypeName, int* TypeIdx); + int __fastcall GetTypeIdxByUID(char* UID); + int __fastcall GetVarIdx(WORD* ModuleIDs, char* VarName); + int __fastcall GetResStrIdx(int from, char* ResStrContext); + int __fastcall GetResStrIdx(WORD ModuleID, char* ResStrContext); + int __fastcall GetResStrIdx(WORD* ModuleIDs, char* ResStrName); + int __fastcall GetProcIdx(WORD ModuleID, char* ProcName); + int __fastcall GetProcIdx(WORD ModuleID, char* ProcName, BYTE* code); + int __fastcall GetProcIdx(WORD* ModuleIDs, char* ProcName, BYTE* code); + bool __fastcall GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx); + bool __fastcall GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx, int* DumpSize); + MConstInfo* __fastcall GetConstInfo(int AConstIdx, DWORD AFlags, MConstInfo* cInfo); + MProcInfo* __fastcall GetProcInfo(char* ProcName, DWORD AFlags, MProcInfo* pInfo, int* procIdx); + MProcInfo* __fastcall GetProcInfo(int AProcIdx, DWORD AFlags, MProcInfo* pInfo); + MTypeInfo* __fastcall GetTypeInfo(int ATypeIdx, DWORD AFlags, MTypeInfo* tInfo); + MVarInfo* __fastcall GetVarInfo(int AVarIdx, DWORD AFlags, MVarInfo* vInfo); + MResStrInfo* __fastcall GetResStrInfo(int AResStrIdx, DWORD AFlags, MResStrInfo* rsInfo); + int __fastcall ScanCode(BYTE* code, DWORD* CodeFlags, DWORD CodeSz, MProcInfo* pInfo); + WORD* __fastcall GetModuleUses(WORD ModuleID); + int __fastcall GetProcUses(char* ProcName, WORD* uses); + WORD* __fastcall GetTypeUses(char* TypeName); + WORD* __fastcall GetConstUses(char* ConstName); + String __fastcall GetProcPrototype(int ProcIdx); + String __fastcall GetProcPrototype(MProcInfo* pInfo); + bool __fastcall IsUsedProc(int AIdx); + void __fastcall SetUsedProc(int AIdx); + bool __fastcall GetKBProcInfo(String typeName, MProcInfo* procInfo, int* procIdx); + bool __fastcall GetKBTypeInfo(String typeName, MTypeInfo* typeInfo); + bool __fastcall GetKBPropertyInfo(String className, String propName, MTypeInfo* typeInfo); + String __fastcall IsPropFunction(String className, String procName); + DWORD Version; + int ModuleCount; + OFFSETSINFO *ModuleOffsets; + WORD *Mods; + BYTE *UsedProcs; + const OFFSETSINFO *ConstOffsets; + const OFFSETSINFO *TypeOffsets; + const OFFSETSINFO *VarOffsets; + const OFFSETSINFO *ResStrOffsets; + const OFFSETSINFO *ProcOffsets; + +private: + bool Inited; + FILE *Handle; + bool __fastcall CheckKBFile(); + + long SectionsOffset; + //Modules + int MaxModuleDataSize; + //Consts + int ConstCount; + int MaxConstDataSize; + //Types + int TypeCount; + int MaxTypeDataSize; + //Vars + int VarCount; + int MaxVarDataSize; + //ResStr + int ResStrCount; + int MaxResStrDataSize; + //Procs + int MaxProcDataSize; + int ProcCount; + + //as temp test (global KB file cache in mem) + const BYTE *KBCache; + long SizeKBFile; + String NameKBFile; + +}; +//--------------------------------------------------------------------------- +#endif + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..325ae30 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2006-2018 crypto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Legend.cpp b/Legend.cpp new file mode 100644 index 0000000..60ed144 --- /dev/null +++ b/Legend.cpp @@ -0,0 +1,32 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Legend.h" +#include "Misc.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFLegend_11011981 *FLegend_11011981; +//--------------------------------------------------------------------------- +__fastcall TFLegend_11011981::TFLegend_11011981(TComponent* Owner) + : TForm(Owner) +{ + lblUnitStd->Font->Color = (TColor)0xC08000; //blue + lblUnitUser->Font->Color = (TColor)0x00B000; //green + lblUnitTrivial->Font->Color = (TColor)0x0000B0; //brown + lblUnitUserUnk->Font->Color = (TColor)0x8080FF; //red +} +//--------------------------------------------------------------------------- +void __fastcall TFLegend_11011981::FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + if (VK_ESCAPE == Key) Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFLegend_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/Legend.dfm b/Legend.dfm similarity index 100% rename from Sources/Forms/Legend.dfm rename to Legend.dfm diff --git a/Legend.h b/Legend.h new file mode 100644 index 0000000..8af52fd --- /dev/null +++ b/Legend.h @@ -0,0 +1,40 @@ +//--------------------------------------------------------------------------- +#ifndef LegendH +#define LegendH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFLegend_11011981 : public TForm +{ +__published: // IDE-managed Components + TGroupBox *gb1; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label5; + TLabel *lblUnitStd; + TLabel *lblUnitUser; + TLabel *lblUnitTrivial; + TLabel *lblUnitUserUnk; + TGroupBox *gb2; + TLabel *Label4; + TLabel *Label6; + TLabel *Label7; + TLabel *lblInit; + TLabel *lblFin; + TLabel *lblUnk; + TButton *btnOK; + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall FormCreate(TObject *Sender); +private: // User declarations +public: // User declarations + __fastcall TFLegend_11011981(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFLegend_11011981 *FLegend_11011981; +//--------------------------------------------------------------------------- +#endif diff --git a/Main.cpp b/Main.cpp new file mode 100644 index 0000000..dd24b98 --- /dev/null +++ b/Main.cpp @@ -0,0 +1,14114 @@ +//--------------------------------------------------------------------------- +#define NO_WIN32_LEAN_AND_MEAN +#include +#pragma hdrstop + +#include "SyncObjs.hpp" +#include +#include +#include +#include +#include +#include "Main.h" +#include "Misc.h" +#include "Threads.h" +#include "ProgressBar.h" +#include "TypeInfo.h" +#include "StringInfo.h" +#include "StrUtils.hpp" +#include "FindDlg.h" +#include "InputDlg.h" +#include "Disasm.h" +#include "Explorer.h" +#include "KBViewer.h" +#include "EditFunctionDlg.h" +#include "EditFieldsDlg.h" +#include "AboutDlg.h" +#include "Legend.h" +#include "IDCGen.h" +#include "IdcSplitSize.h" +#include "Decompiler.h" +#include "Hex2Double.h" +#include "Plugins.h" +#include "ActiveProcesses.h" +#include +#include +#include +#include +#include +#include +#include +/* +//----Highlighting----------------------------------------------------------- +#include "Highlight.h" +DWORD DelphiLbId; +int DelphiThemesCount; +//----Highlighting----------------------------------------------------------- +*/ +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "TntStdCtrls" +#pragma resource "*.dfm" +#pragma resource "idr_manifest.res" +//--------------------------------------------------------------------------- +//as statistics of analysis flow +//unsigned long stat_GetClassAdr_calls = 0; +//unsigned long stat_GetClassAdr_adds = 0; +//--------------------------------------------------------------------------- +String IDRVersion = "01.04.2017"; +//--------------------------------------------------------------------------- +SysProcInfo SysProcs[] = { + {"@HandleFinally", 0}, + {"@HandleAnyException", 0}, + {"@HandleOnException", 0}, + {"@HandleAutoException", 0}, + {"@RunError", 0}, + //{"@Halt", 0}, + {"@Halt0", 0}, + {"@AbstractError", 0}, + {0, 0} +}; + +SysProcInfo SysInitProcs[] = { + {"@InitExe", 0}, + {"@InitLib", 0}, + {0, 0} +}; +//Image Code +//|===========|======================================| +//ImageBase CodeBase +//--------------------------------------------------------------------------- +char StringBuf[MAXSTRBUFFER]; //Buffer to make string + +extern char* Reg32Tab[8]; +extern char* Reg16Tab[8]; +extern char* Reg8Tab[8]; +extern char* SegRegTab[8]; +extern char* RepPrefixTab[4]; + +extern RegClassInfo RegClasses[]; + +String cmdAdr = ""; + +int dummy = 0; //for debugging purposes!!! + +MDisasm Disasm; //Äèçàññåìáëåð äëÿ àíàëèçàòîðà êîäà +MKnowledgeBase KnowledgeBase; +TResourceInfo *ResInfo = 0; //Information about forms +int CodeHistorySize; //Current size of Code navigation History Array +int CodeHistoryPtr; //Curent pointer of Code navigation History Array +int CodeHistoryMax; //Max pointer position of Code navigation History Array (for ->) +DynamicArray CodeHistory; //Code navigation History Array + +TAnalyzeThread *AnalyzeThread = 0; //Ïîòîê äëÿ ôîíîâîãî àíàëèçà êîäà +int AnalyzeThreadRetVal = 0; +bool SourceIsLibrary = false; +bool ClassTreeDone; +bool ProjectModified = false; +bool UserKnowledgeBase = false; +bool SplitIDC = false; +bool BCB = false; +int SplitSize = 0; +UINT CodePage; +//Common variables +String IDPFile; +int MaxBufLen; //Ìàêñèìàëüíàÿ äëèíà áóôåðà (äëÿ çàãðóçêè) +int DelphiVersion; +DWORD EP; +DWORD ImageBase; +DWORD ImageSize; +DWORD TotalSize; //Size of sections CODE + DATA +DWORD CodeBase; +DWORD CodeSize; +DWORD CodeStart; +DWORD DataBase = 0; +DWORD DataSize = 0; +DWORD DataStart = 0; +BYTE *Image = 0; +DWORD *Flags = 0; //flags for used data +PInfoRec *Infos = 0; //Array of pointers to store items data +TStringList *BSSInfos = 0; //Data from BSS +BYTE *Code = 0; +BYTE *Data = 0; + +TList *ExpFuncList; //Exported functions list (temporary) +TList *ImpFuncList; //Imported functions list (temporary) +TStringList *ImpModuleList; //Imported modules list (temporary) +TList *SegmentList; //Information about Image Segments +TList *VmtList; //VMT list + +//Units +int UnitsNum = 0; +TList *Units = 0; +int UnitSortField = 0; //0 - by address, 1 - by initialization order, 2 - by name +//Types +TList *OwnTypeList = 0; +int RTTISortField = 0; //0 - by address, 1 - by initialization order, 2 - by name + +DWORD CurProcAdr; +int CurProcSize; +String SelectedAsmItem = ""; //Selected item in Asm Listing +String SelectedSourceItem = ""; //Selected item in Source Code +DWORD CurUnitAdr; +DWORD HInstanceVarAdr; +DWORD LastTls; //Last bust index Tls shows how many ThreadVars in program +int Reserved; +int LastResStrNo = 0; //Last ResourceStringNo +DWORD CtdRegAdr; //Procedure CtdRegAdr address + +int cVmtSelfPtr = 0; +int cVmtIntfTable = 0; +int cVmtAutoTable = 0; +int cVmtInitTable = 0; +int cVmtTypeInfo = 0; +int cVmtFieldTable = 0; +int cVmtMethodTable = 0; +int cVmtDynamicTable = 0; +int cVmtClassName = 0; +int cVmtInstanceSize = 0; +int cVmtParent = 0; +int cVmtEquals = 0; +int cVmtGetHashCode = 0; +int cVmtToString = 0; +int cVmtSafeCallException = 0; +int cVmtAfterConstruction = 0; +int cVmtBeforeDestruction = 0; +int cVmtDispatch = 0; +int cVmtDefaultHandler = 0; +int cVmtNewInstance = 0; +int cVmtFreeInstance = 0; +int cVmtDestroy = 0; + +//as +//class addresses cache +typedef std::map TClassAdrMap; +TClassAdrMap classAdrMap; + +void __fastcall ClearClassAdrMap(); +//String __fastcall UnmangleName(char* Name); + +TCriticalSection *CrtSection = 0; +TFMain_11011981 *FMain_11011981; +//--------------------------------------------------------------------------- +__fastcall TFMain_11011981::TFMain_11011981(TComponent* Owner) + : dragdropHelper(Handle), TForm(Owner) +{ + CrtSection = new TCriticalSection; +} +//--------------------------------------------------------------------------- +__fastcall TFMain_11011981::~TFMain_11011981() +{ + if (CrtSection) delete CrtSection; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormClose(TObject *Sender, + TCloseAction &Action) +{ + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + switch (Key) + { + case 'G': + GoToAddress(); + break; + case 'N': + NamePosition(); + break; + case 'F': //CTRL + F (1st search on different areas) + { + if (Shift.Contains(ssCtrl)) + { + switch (WhereSearch) + { + case SEARCH_UNITS: + miSearchUnitClick(Sender); + break; + case SEARCH_UNITITEMS: + miSearchItemClick(Sender); + break; + case SEARCH_RTTIS: + miSearchRTTIClick(Sender); + break; + case SEARCH_FORMS: + miSearchFormClick(Sender); + break; + case SEARCH_CLASSVIEWER: + miSearchVMTClick(Sender); + break; + case SEARCH_STRINGS: + miSearchStringClick(Sender); + break; + case SEARCH_NAMES: + miSearchNameClick(Sender); + break; + //todo rest of locations + } + } + break; + } + case VK_F3: // F3 - (2nd search, continue search with same text) + switch (WhereSearch) + { + case SEARCH_UNITS: + FindText(UnitsSearchText); + break; + case SEARCH_UNITITEMS: + FindText(UnitItemsSearchText); + break; + case SEARCH_RTTIS: + FindText(RTTIsSearchText); + break; + case SEARCH_FORMS: + FindText(FormsSearchText); + break; + case SEARCH_CLASSVIEWER: + FindText(VMTsSearchText); + break; + case SEARCH_STRINGS: + FindText(StringsSearchText); + break; + case SEARCH_NAMES: + FindText(NamesSearchText); + break; + } + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::Units1Click(TObject *Sender) +{ + //if (tsUnits->Enabled) + //{ + pcInfo->ActivePage = tsUnits; + if (lbUnits->CanFocus()) ActiveControl = lbUnits; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::RTTI1Click(TObject *Sender) +{ + //if (tsRTTIs->Enabled) + //{ + pcInfo->ActivePage = tsRTTIs; + if (lbRTTIs->CanFocus()) ActiveControl = lbRTTIs; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::Forms1Click(TObject *Sender) +{ + //if (tsForms->Enabled) + //{ + pcInfo->ActivePage = tsForms; + if (lbForms->CanFocus()) ActiveControl = lbForms; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::CodeViewer1Click(TObject *Sender) +{ + //if (tsCodeView->Enabled) + //{ + pcWorkArea->ActivePage = tsCodeView; + if (lbCode->CanFocus()) ActiveControl = lbCode; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ClassViewer1Click(TObject *Sender) +{ + //if (tsClassView->Enabled) + //{ + pcWorkArea->ActivePage = tsClassView; + if (!rgViewerMode->ItemIndex) + if (tvClassesFull->CanFocus()) ActiveControl = tvClassesFull; + else + if (tvClassesShort->CanFocus()) ActiveControl = tvClassesShort; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::Strings1Click(TObject *Sender) +{ + //if (tsStrings->Enabled) + //{ + pcWorkArea->ActivePage = tsStrings; + if (lbStrings->CanFocus()) ActiveControl = lbStrings; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::Names1Click(TObject *Sender) +{ + //if (tsNames->Enabled) + //{ + pcWorkArea->ActivePage = tsNames; + if (lbNames->CanFocus()) ActiveControl = lbNames; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::SourceCode1Click(TObject *Sender) +{ + //if (tsSourceCode->Enabled) + //{ + pcWorkArea->ActivePage = tsSourceCode; + if (lbSourceCode->CanFocus()) ActiveControl = lbSourceCode; + //} +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExitClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::Init() +{ + IDPFile = ""; + UnitsNum = 0; + CurProcAdr = 0; + CurProcSize = 0; + SelectedAsmItem = ""; + CurUnitAdr = 0; + CodeHistoryPtr = -1; + CodeHistorySize = 0;//HISTORY_CHUNK_LENGTH; + CodeHistory.Length = CodeHistorySize; + CodeHistoryMax = CodeHistoryPtr; + + DelphiVersion = -1; + Caption = "Interactive Delphi Reconstructor by crypto"; + + HInstanceVarAdr = 0xFFFFFFFF; + LastTls = 0; + CtdRegAdr = 0; + + WhereSearch = SEARCH_UNITS; + UnitsSearchFrom = -1; + UnitsSearchText = ""; + + RTTIsSearchFrom = -1; + RTTIsSearchText = ""; + + FormsSearchFrom = -1; + FormsSearchText = ""; + + UnitItemsSearchFrom = -1; + UnitItemsSearchText = ""; + + TreeSearchFrom = 0; + BranchSearchFrom = 0; + VMTsSearchText = ""; + + StringsSearchFrom = 0; + StringsSearchText = ""; + + NamesSearchFrom = 0; + NamesSearchText = ""; + + //Init Menu + miLoadFile->Enabled = true; + miOpenProject->Enabled = true; + miMRF->Enabled = true; + miSaveProject->Enabled = false; + miSaveDelphiProject->Enabled = false; + miExit->Enabled = true; + miMapGenerator->Enabled = false; + miCommentsGenerator->Enabled = false; + miIDCGenerator->Enabled = false; + miHiewGenerator->Enabled = false; + miLister->Enabled = false; + miClassTreeBuilder->Enabled = false; + miKBTypeInfo->Enabled = false; + miCtdPassword->Enabled = false; + miHex2Double->Enabled = false; + + //Init Units + lbUnits->Clear(); + miRenameUnit->Enabled = false; + miSearchUnit->Enabled = false; + miSortUnits->Enabled = false; + miCopyList->Enabled = false; + UnitSortField = 0; + miSortUnitsByAdr->Checked = true; + miSortUnitsByOrd->Checked = false; + miSortUnitsByNam->Checked = false; + tsUnits->Enabled = false; + + //Init RTTIs + lbRTTIs->Clear(); + miSearchRTTI->Enabled = false; + miSortRTTI->Enabled = false; + RTTISortField = 0; + miSortRTTIsByAdr->Checked = true; + miSortRTTIsByKnd->Checked = false; + miSortRTTIsByNam->Checked = false; + tsRTTIs->Enabled = false; + + //Init Forms + lbForms->Clear(); + lbAliases->Clear(); + lClassName->Caption = ""; + cbAliases->Clear(); + rgViewFormAs->ItemIndex = 0; + tsForms->Enabled = false; + + //Init Code + lProcName->Caption = ""; + lbCode->Clear(); + lbCode->ScrollWidth = 0; + miGoTo->Enabled = false; + miExploreAdr->Enabled = false; + miName->Enabled = false; + miViewProto->Enabled = false; + miEditFunctionC->Enabled = false; + miXRefs->Enabled = false; + miSwitchFlag->Enabled = false; + bEP->Enabled = false; + bDecompile->Enabled = false; + bCodePrev->Enabled = false; + bCodeNext->Enabled = false; + tsCodeView->Enabled = false; + lbCXrefs->Clear(); + lbCXrefs->Visible = true; + + //Init Strings + lbStrings->Clear(); + miSearchString->Enabled = false; + tsStrings->Enabled = false; + + //Init Names + lbNames->Clear(); + tsNames->Enabled = false; + + //Xrefs + lbSXrefs->Clear(); + lbSXrefs->Visible = true; + + //Init Unit Items + lbUnitItems->Clear(); + lbUnitItems->ScrollWidth = 0; + miEditFunctionI->Enabled = false; + miFuzzyScanKB->Enabled = false; + miSearchItem->Enabled = false; + + //Init ClassViewer + ClassTreeDone = false; + tvClassesFull->Items->Clear(); + tvClassesShort->Items->Clear(); + tvClassesShort->BringToFront(); + rgViewerMode->ItemIndex = 1; //Short View + tsClassView->Enabled = false; + + ClearTreeNodeMap(); + ClearClassAdrMap(); + + Update(); + Sleep(0); + + ProjectLoaded = false; + ProjectModified = false; + UserKnowledgeBase = false; + SourceIsLibrary = false; +} +//--------------------------------------------------------------------------- +PImportNameRec __fastcall TFMain_11011981::GetImportRec(DWORD adr) +{ + for (int n = 0; n < ImpFuncList->Count; n++) + { + PImportNameRec recI = (PImportNameRec)ImpFuncList->Items[n]; + if (adr == recI->address) + return recI; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FindExports() +{ + int pos; + + for (int i = 0; i < ExpFuncList->Count; i++) + { + PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[i]; + DWORD Adr = recE->address; + if (IsValidImageAdr(Adr) && (pos = Adr2Pos(Adr)) != -1) + { + PInfoRec recN = new InfoRec(pos, ikRefine); + recN->SetName(recE->name); + recN->procInfo->flags = 3; //stdcall + Infos[pos] = recN; + SetFlag(cfProcStart | cfExport, pos); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FindImports() +{ + char *b, *e; + int pos; + String name; + + for (int i = 0; i < TotalSize - 6; i++) + { + if (Code[i] == 0xFF && Code[i + 1] == 0x25) + { + DWORD adr = *((DWORD*)(Code + i + 2)); + PImportNameRec recI = GetImportRec(adr); + if (recI) + { + //name = UnmangleName(recI->name); + if (!Infos[i]) + { + PInfoRec recN = new InfoRec(i, ikRefine); + recN->procInfo->procSize = 6; + SetFlag(cfProcStart, i); + SetFlag(cfProcEnd, i + 6); + + if (recI->name.Pos("@Initialization$") || recI->name.Pos("@Finalization$")) + { + recN->SetName(recI->module + "." + recI->name); + } + else + { + b = strchr(recI->name.c_str() + 1, '@'); + if (b) + { + e = strchr(b + 1, '$'); + if (e) + { + if (*(e - 1) != '@') + recN->SetName(String(b + 1, e - b - 1)); + else + recN->SetName(String(b + 1, e - b - 2)); + if (recI->name.Pos("$bctr$")) + { + recN->ConcatName("@Create"); + recN->kind = ikConstructor; + } + else if (recI->name.Pos("$bdtr$")) + { + recN->ConcatName("@Destroy"); + recN->kind = ikDestructor; + } + pos = recN->GetName().Pos("@"); + if (pos > 1) recN->GetName()[pos] = '.'; + } + } + else + recN->SetName(recI->module + "." + recI->name); + } + for (int n = 0; SysProcs[n].name; n++) + { + if (recI->name.Pos(SysProcs[n].name)) + { + SysProcs[n].impAdr = Pos2Adr(i); + break; + } + } + SetFlag(cfImport, i); + } + SetFlags(cfCode, i, 6); + } + } + } +} +//--------------------------------------------------------------------------- +//"Âøèâàåò" VMT â êîä ñ ïîçèöèè pos +void __fastcall TFMain_11011981::StrapVMT(int pos, int ConstId, MConstInfo* ConstInfo) +{ + if (!ConstInfo) return; + + //Check dump VMT + BYTE *dump = ConstInfo->Dump; + BYTE *relocs = ConstInfo->Dump + ConstInfo->DumpSz; + bool match = true; + for (int n = 0; n < ConstInfo->DumpSz; n++) + { + if (relocs[n] != 0xFF && Code[pos + n] != dump[n]) + { + match = false; + break; + } + } + if (!match) return; + + SetFlags(cfData , pos - 4, ConstInfo->DumpSz + 4); + + int Idx, Pos, VMTOffset = cVmtSelfPtr + 4; + //"Strap" fixups + //Get used modules array + WORD *uses = KnowledgeBase.GetModuleUses(ConstInfo->ModuleID); + //Begin fixups data + BYTE *p = ConstInfo->Dump + 2*(ConstInfo->DumpSz); + FIXUPINFO fixupInfo; + MProcInfo aInfo; MProcInfo* pInfo = &aInfo; + for (int n = 0; n < ConstInfo->FixupNum; n++) + { + fixupInfo.Type = *p; p++; + fixupInfo.Ofs = *((DWORD*)p); p += 4; + WORD Len = *((WORD*)p); p += 2; + fixupInfo.Name = p; p += Len + 1; + //Name begins with _D - skip it + if (fixupInfo.Name[0] == '_' && fixupInfo.Name[1] == 'D') continue; + //In VMT all fixups has type 'A' + DWORD Adr = *((DWORD*)(Code + pos + fixupInfo.Ofs)); + + VMTOffset = cVmtSelfPtr + 4 + fixupInfo.Ofs; + + if (VMTOffset == cVmtIntfTable) + { + if (IsValidCodeAdr(Adr) && !Infos[Adr2Pos(Adr)]) + { + //Strap IntfTable + Idx = KnowledgeBase.GetProcIdx(ConstInfo->ModuleID, fixupInfo.Name, Code + Adr2Pos(Adr)); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); + } + } + } + } + continue; + } + if (VMTOffset == cVmtAutoTable) + { + //Strap AutoTable + //Unknown - no examples + continue; + } + if (VMTOffset == cVmtInitTable) + { + //InitTable ïðåäñòàâëÿåò ñîáîé ññûëêè íà òèïû, êîòîðûå âñòðåòÿòñÿ ïîçæå + continue; + } + if (VMTOffset == cVmtTypeInfo) + { + //Èíôîðìàöèÿ î òèïå óæå îáðàáîòàíà, ïðîïóñêàåì + continue; + } + if (VMTOffset == cVmtFieldTable) + { + //Ïðîïóñêàåì, ïîñêîëüêó áóäåì îáðàáàòûâàòü èíôîðìàöèþ î ïîëÿõ ïîçäíåå + continue; + } + if (VMTOffset == cVmtMethodTable) + { + //Ïðîïóñêàåì, ïîñêîëüêó ìåòîäû áóäóò îáðàáîòàíû ñðåäè ïðî÷èõ ôèêñàïîâ + continue; + } + if (VMTOffset == cVmtDynamicTable) + { + //Ïðîïóñêàåì, ïîñêîëüêó äèíàìè÷åñêèå âûçîâû áóäóò îáðàáîòàíû ñðåäè ïðî÷èõ ôèêñàïîâ + continue; + } + if (VMTOffset == cVmtClassName) + { + //ClassName íå îáðàáàòûâàåì + continue; + } + if (VMTOffset == cVmtParent) + { + //Óêàçûâàåò íà ðîäèòåëüñêèé êëàññ, íå îáðàáàòûâàåì, ïîñêîëüêó îí âñå-ðàâíî âñòðåòèòñÿ îòäåëüíî + continue; + } + if (VMTOffset >= cVmtParent + 4 && VMTOffset <= cVmtDestroy) + { + if (IsValidCodeAdr(Adr) && !Infos[Adr2Pos(Adr)]) + { + Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, Code + Adr2Pos(Adr)); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); + } + } + } + //Code not matched, but prototype may be used + else + { + PInfoRec recN = new InfoRec(Adr2Pos(Adr), ikRefine); + recN->SetName(fixupInfo.Name); + //Prototype??? + if (uses) + { + for (int m = 0; uses[m] != 0xFFFF; m++) + { + Idx = KnowledgeBase.GetProcIdx(uses[m], fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (KnowledgeBase.GetProcInfo(Idx, INFO_ARGS, pInfo)) + { + switch (pInfo->MethodKind) + { + case 'C': + recN->kind = ikConstructor; + break; + case 'D': + recN->kind = ikDestructor; + break; + case 'P': + recN->kind = ikProc; + break; + case 'F': + recN->kind = ikFunc; + recN->type = pInfo->TypeDef; + break; + } + + if (pInfo->Args) + { + BYTE callKind = pInfo->CallKind; + recN->procInfo->flags |= callKind; + + ARGINFO argInfo; BYTE *pp = pInfo->Args; int ss = 8; + for (int k = 0; k < pInfo->ArgsNum; k++) + { + FillArgInfo(k, callKind, &argInfo, &pp, &ss); + recN->procInfo->AddArg(&argInfo); + } + } + //Set kbIdx for fast search + recN->kbIdx = Idx; + recN->procInfo->flags |= PF_KBPROTO; + } + } + } + } + } + } + continue; + } + //Åñëè àäðåñ â êîäîâîì ñåãìåíòå è ñ íèì íå ñâÿçàíî íèêàêîé èíôîðìàöèè + if (IsValidCodeAdr(Adr) && !Infos[Adr2Pos(Adr)]) + { + //Íàçâàíèå òèïà? + if (!IsFlagSet(cfRTTI, Adr2Pos(Adr))) + { + //Ïðîöåäóðà? + Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, Code + Adr2Pos(Adr)); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); + } + } + } + //Code not matched, but prototype may be used + else + { + PInfoRec recN = new InfoRec(Adr2Pos(Adr), ikRefine); + recN->SetName(fixupInfo.Name); + //Prototype??? + if (uses) + { + for (int m = 0; uses[m] != 0xFFFF; m++) + { + Idx = KnowledgeBase.GetProcIdx(uses[m], fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (KnowledgeBase.GetProcInfo(Idx, INFO_ARGS, pInfo)) + { + switch (pInfo->MethodKind) + { + case 'C': + recN->kind = ikConstructor; + break; + case 'D': + recN->kind = ikDestructor; + break; + case 'P': + recN->kind = ikProc; + break; + case 'F': + recN->kind = ikFunc; + recN->type = pInfo->TypeDef; + break; + } + + if (pInfo->Args) + { + BYTE callKind = pInfo->CallKind; + recN->procInfo->flags |= callKind; + + ARGINFO argInfo; BYTE *pp = pInfo->Args; int ss = 8; + for (int k = 0; k < pInfo->ArgsNum; k++) + { + FillArgInfo(k, callKind, &argInfo, &pp, &ss); + recN->procInfo->AddArg(&argInfo); + } + } + //Set kbIdx for fast search + recN->kbIdx = Idx; + recN->procInfo->flags |= PF_KBPROTO; + } + } + } + } + } + } + continue; + } + } + if (uses) delete[] uses; +} +//--------------------------------------------------------------------------- +//Check possibility of "straping" procedure (only at the first level) +bool __fastcall TFMain_11011981::StrapCheck(int pos, MProcInfo* ProcInfo) +{ + int _ap; + String name, fName, _key; + PInfoRec recN; + + if (!ProcInfo) return false; + + BYTE *dump = ProcInfo->Dump; + //Fixup data begin + BYTE *p = dump + 2*(ProcInfo->DumpSz); + //If procedure is jmp off_XXXXXXXX, return false + if (*dump == 0xFF && *(dump + 1) == 0x25) return false; + + FIXUPINFO fixupInfo; + for (int n = 0; n < ProcInfo->FixupNum; n++) + { + fixupInfo.Type = *p; p++; + fixupInfo.Ofs = *((DWORD*)p); p += 4; + WORD Len = *((WORD*)p); p += 2; + fixupInfo.Name = p; p += Len + 1; + + String fName = String(fixupInfo.Name); + //Fixupname begins with "_Dn_" - skip it + if (fName.Pos("_Dn_") == 1) continue; + //Fixupname begins with "_NF_" - skip it + if (fName.Pos("_NF_") == 1) continue; + //Fixupname is "_DV_" - skip it + if (SameText(fName, "_DV_")) continue; + //Fixupname begins with "_DV_" + if (fName.Pos("_DV_") == 1) + { + char c = fName[5]; + //Fixupname is _DV_number - skip it + if (c >= '0' && c <= '9') continue; + //Else transfrom fixupname to normal + if (fName[Len] == '_') + fName = fName.SubString(5, Len - 5); + else + fName = fName.SubString(5, Len - 4); + } + //Empty fixupname - skip it + if (fName == "") continue; + + DWORD Adr, Ofs, Val = *((DWORD*)(Code + pos + fixupInfo.Ofs)); + if (fixupInfo.Type == 'A' || fixupInfo.Type == 'S') + { + Ofs = *((DWORD*)(dump + fixupInfo.Ofs)); + Adr = Val - Ofs; + if (IsValidImageAdr(Adr)) + { + _ap = Adr2Pos(Adr); recN = GetInfoRec(Adr); + if (recN && recN->HasName()) + { + //If not import call just compare names + if (_ap >= 0 && !IsFlagSet(cfImport, _ap)) + { + if (!recN->SameName(fName)) return false; + } + //Else may be partial unmatching + else + { + name = ExtractProcName(recN->GetName()); + if (!SameText(name, fName) && !SameText(name.SubString(1, name.Length() - 1), fName)) + return false; + } + } + } + } + else if (fixupInfo.Type == 'J') + { + Adr = CodeBase + pos + fixupInfo.Ofs + 4 + Val; + if (IsValidCodeAdr(Adr)) + { + _ap = Adr2Pos(Adr); recN = GetInfoRec(Adr); + if (recN && recN->HasName()) + { + //If not import call just compare names + if (_ap >= 0 && !IsFlagSet(cfImport, _ap)) + { + if (!recN->SameName(fName)) return false; + } + //Else may be partial unmatching + else + { + name = ExtractProcName(recN->GetName()); + if (!SameText(name, fName)) + { + String name1 = name.SubString(1, name.Length() - 1);//Trim last symbol ('A','W') - GetWindowLongW(A) + if (!SameText(fName.SubString(1, name1.Length()), name1)) return false; + } + } + } + } + } + else if (fixupInfo.Type == 'D') + { + Adr = Val; + if (IsValidImageAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN && recN->HasName()) + { + if (!recN->SameName(fName)) return false; + } + } + } + } + return true; +} +//--------------------------------------------------------------------------- +//"Strap" procedure ProcIdx int code from position pos +void __fastcall TFMain_11011981::StrapProc(int pos, int ProcIdx, MProcInfo* ProcInfo, bool useFixups, int procSize) +{ + if (!ProcInfo) return; + //Citadel!!! + if (SameText(ProcInfo->ProcName, "CtdReg")) + { + if (procSize == 1) return; + CtdRegAdr = Pos2Adr(pos); + } + DWORD ProcStart = Pos2Adr(pos); + DWORD ProcEnd = ProcStart + procSize; +//!!! +if(ProcStart == 0x04061A8) +pos = pos; + + String ModuleName = KnowledgeBase.GetModuleName(ProcInfo->ModuleID); + if (!IsUnitExist(ModuleName)) + { + //Get unit by pos + PUnitRec recU = GetUnit(Pos2Adr(pos)); + if (recU) + { + SetUnitName(recU, ModuleName); + recU->kb = true; + } + } + BYTE* p; PInfoRec recN; + if (ProcInfo->DumpType == 'D') + { + SetFlags(cfData, pos, procSize); + } + else + { + SetFlags(cfCode, pos, procSize); + //Mark proc begin + SetFlag(cfProcStart, pos); + //SetFlag(cfProcEnd, pos + procSize - 1); + + recN = GetInfoRec(Pos2Adr(pos)); + if (!recN) recN = new InfoRec(pos, ikRefine); + //Mark proc end + recN->procInfo->procSize = procSize; + + switch (ProcInfo->MethodKind) + { + case 'C': + recN->kind = ikConstructor; + break; + case 'D': + recN->kind = ikDestructor; + break; + case 'F': + recN->kind = ikFunc; + recN->type = ProcInfo->TypeDef; + break; + case 'P': + recN->kind = ikProc; + break; + } + + recN->kbIdx = ProcIdx; + recN->SetName(ProcInfo->ProcName); + //Get Args + if (!recN->MakeArgsManually()) + { + BYTE callKind = ProcInfo->CallKind; + recN->procInfo->flags |= callKind; + + int aa = 0, ss = 8; + ARGINFO argInfo; + p = ProcInfo->Args; + if (p) + { + for (int k = 0; k < ProcInfo->ArgsNum; k++) + { + argInfo.Tag = *p; p++; + int locflags = *((int*)p); p += 4; + + if ((locflags & 7) == 1) argInfo.Tag = 0x23; //Add by ZGL + + argInfo.Register = (locflags & 8); + //Ndx + int ndx = *((int*)p); p += 4; + + argInfo.Size = 4; + WORD wlen = *((WORD*)p); p += 2; + argInfo.Name = String((char*)p, wlen); p += wlen + 1; + wlen = *((WORD*)p); p += 2; + argInfo.TypeDef = TrimTypeName(String((char*)p, wlen)); p += wlen + 1; + //Some correction of knowledge base + if (SameText(argInfo.Name, "Message") && SameText(argInfo.TypeDef, "void")) + { + argInfo.Name = "Msg"; + argInfo.TypeDef = "TMessage"; + } + + if (SameText(argInfo.TypeDef, "String")) argInfo.TypeDef = "AnsiString"; + if (SameText(argInfo.TypeDef, "Int64") || + SameText(argInfo.TypeDef, "Real") || + SameText(argInfo.TypeDef, "Real48") || + SameText(argInfo.TypeDef, "Comp") || + SameText(argInfo.TypeDef, "Double") || + SameText(argInfo.TypeDef, "Currency") || + SameText(argInfo.TypeDef, "TDateTime")) + argInfo.Size = 8; + if (SameText(argInfo.TypeDef, "Extended")) argInfo.Size = 12; + + if (!callKind) + { + if (aa < 3 && argInfo.Size == 4) + { + argInfo.Ndx = aa; + aa++; + } + else + { + argInfo.Ndx = ss; + ss += argInfo.Size; + } + } + else + { + argInfo.Ndx = ss; + ss += argInfo.Size; + } + recN->procInfo->AddArg(&argInfo); + } + } + } + recN->procInfo->flags |= PF_KBPROTO; + } + //Fix used procedure + KnowledgeBase.SetUsedProc(ProcIdx); + + if (useFixups && ProcInfo->FixupNum) + { + //Get array of used modules + int Idx, size; + WORD *uses = KnowledgeBase.GetModuleUses(ProcInfo->ModuleID); + //Íà÷àëî äàííûõ ïî ôèêñàïàì + p = ProcInfo->Dump + 2*ProcInfo->DumpSz; + FIXUPINFO fixupInfo; + + MConstInfo acInfo; + MConstInfo *cInfo = &acInfo; + MTypeInfo atInfo; + MTypeInfo *tInfo = &atInfo; + MVarInfo avInfo; + MVarInfo *vInfo = &avInfo; + MResStrInfo arsInfo; + MResStrInfo *rsInfo = &arsInfo; + MProcInfo aInfo; MProcInfo* pInfo = &aInfo; + DWORD Adr, Adr1, Ofs, Val; + WORD Len; + String fName; + + for (int n = 0; n < ProcInfo->FixupNum; n++) + { + fixupInfo.Type = *p; p++; + fixupInfo.Ofs = *((DWORD*)p); p += 4; + Len = *((WORD*)p); p += 2; + fixupInfo.Name = p; p += Len + 1; + fName = String(fixupInfo.Name, Len); + //Fixupname begins with _Dn_ - skip it + if (fName.Pos("_Dn_") == 1) continue; + //Fixupname begins with _NF_ - skip it + if (fName.Pos("_NF_") == 1) continue; + //Fixupname is "_DV_" - skip it + if (SameText(fName, "_DV_")) continue; + //Fixupname begins with _DV_ + if (fName.Pos("_DV_") == 1) + { + char c = fName[5]; + //Fixupname is _DV_number - skip it + if (c >= '0' && c <= '9') continue; + //Else transfrom fixupname to normal + if (fName[Len] == '_') + fName = fName.SubString(5, Len - 5); + else + fName = fName.SubString(5, Len - 4); + } + if (fName == "" || fName == ".") continue; + + Val = *((DWORD*)(Code + pos + fixupInfo.Ofs)); + //FixupName is the same as ProcName + if (SameText(fName, ProcInfo->ProcName)) + { + //!!! + //Need to use this information: + //CaseStudio, 405ae4 - call [offs+4*eax] - how to use offs? And offs has cfLoc + //Val inside procedure - possible jump address for switch (or call) + if (fixupInfo.Type == 'J') + { + Adr = CodeBase + pos + fixupInfo.Ofs + Val + 4; + if (Adr >= ProcStart && Adr < ProcEnd) + SetFlag(cfLoc | cfEmbedded, Adr2Pos(Adr)); + } + continue; + } + //Ñíà÷àëà ïîäñ÷èòàåì àäðåñ, à ïîòîì áóäåì ïûòàòüñÿ îïðåäåëÿòü ñåêöèþ + if (fixupInfo.Type == 'A' || fixupInfo.Type == 'S' || fixupInfo.Type == '4' || fixupInfo.Type == '8') + { + //Ñìîòðèì, êàêàÿ âåëè÷èíà ñòîèò â äàìïå â ïîçèöèè ôèêñàïà + Ofs = *((DWORD*)(ProcInfo->Dump + fixupInfo.Ofs)); + Adr = Val - Ofs; + } + else if (fixupInfo.Type == 'J') + { + Adr = CodeBase + pos + fixupInfo.Ofs + Val + 4; + } + else if (fixupInfo.Type == 'D' || fixupInfo.Type == '6' || fixupInfo.Type == '5') + { + Adr = Val; + } + else + { + ShowMessage("Unknown fixup type:" + String(fixupInfo.Type)); + } + + bool isHInstance = (stricmp(fixupInfo.Name, "HInstance") == 0); + if (!IsValidImageAdr(Adr)) + { + //Ïîêà çäåñü íàáëþäàëèñü ëèøü îäíè ThreadVars è TlsLast + if (!stricmp(fixupInfo.Name, "TlsLast")) + { + LastTls = Val; + } + else + { + recN = GetInfoRec(Pos2Adr(pos + fixupInfo.Ofs)); + if (!recN) + { + recN = new InfoRec(pos + fixupInfo.Ofs, ikData); + recN->SetName(fixupInfo.Name); + //Îïðåäåëèì òèï Var + Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.VarOffsets[Idx].NamId; + if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) + { + if (vInfo->Type == 'T') + recN->kind = ikThreadVar; + recN->kbIdx = Idx; + recN->type = TrimTypeName(vInfo->TypeDef); + } + } + } + } + continue; + } + + if (Adr >= ProcStart && Adr < ProcEnd) continue; + + if (isHInstance) + { + Adr1 = *((DWORD*)(Code + Adr2Pos(Adr))); + if (IsValidImageAdr(Adr1)) + HInstanceVarAdr = Adr1; + else + HInstanceVarAdr = Adr; + } + + int Sections = KnowledgeBase.GetItemSection(uses, fixupInfo.Name); + //Àäðåñ â êîäîâîì ñåãìåíòå âíå òåëà ñàìîé ôóíêöèè + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (!recN) + { + switch (Sections) + { + case KB_CONST_SECTION: + Idx = KnowledgeBase.GetConstIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ConstOffsets[Idx].NamId; + //Åñëè èìÿ íà÷èíàåòñÿ íà _DV_, çíà÷èò ýòî VMT + if (!memcmp(fixupInfo.Name, "_DV_", 4)) + { + if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) + StrapVMT(Adr2Pos(Adr) + 4, Idx, cInfo); + } + else + { + } + } + break; + case KB_TYPE_SECTION: + Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.TypeOffsets[Idx].NamId; + if (KnowledgeBase.GetTypeInfo(Idx, 0, tInfo)) + { + recN = new InfoRec(Adr2Pos(Adr), ikData); + recN->kbIdx = Idx; + recN->SetName(tInfo->TypeName); + } + } + break; + case KB_VAR_SECTION: + Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.VarOffsets[Idx].NamId; + if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) + { + recN = new InfoRec(Adr2Pos(Adr), ikData); + recN->kbIdx = Idx; + recN->SetName(vInfo->VarName); + recN->type = TrimTypeName(vInfo->TypeDef); + } + } + break; + case KB_RESSTR_SECTION: + Idx = KnowledgeBase.GetResStrIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ResStrOffsets[Idx].NamId; + if (KnowledgeBase.GetResStrInfo(Idx, 0, rsInfo)) + { + recN = new InfoRec(Adr2Pos(Adr), ikData); + recN->kbIdx = Idx; + recN->SetName(rsInfo->ResStrName); + recN->type = rsInfo->TypeDef; + } + } + break; + case KB_PROC_SECTION: + Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, Code + Adr2Pos(Adr)); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); + } + } + else + { + Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, 0); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + if (!SameText(fName, "@Halt")) + { + StrapProc(Adr2Pos(Adr), Idx, pInfo, false, EstimateProcSize(Adr)); + } + else + { + DISINFO _disInfo; + int _bytes = EstimateProcSize(Adr); + while (_bytes > 0) + { + int _instrlen = Disasm.Disassemble(Code + Adr2Pos(Adr), (__int64)Adr, &_disInfo, 0); + if (_disInfo.Branch && !_disInfo.Conditional) + { + Adr = _disInfo.Immediate; + Idx = KnowledgeBase.GetProcIdx(uses, "@Halt0", 0); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + StrapProc(Adr2Pos(Adr), Idx, pInfo, false, EstimateProcSize(Adr)); + } + } + break; + } + _bytes -= _instrlen; + } + } + } + } + } + + } + break; + } + continue; + } + } + //Àäðåñ â ñåêöèè DATA + if (IsValidImageAdr(Adr)) + { + int _pos = Adr2Pos(Adr); + if (_pos >= 0) + { + recN = GetInfoRec(Adr); + if (!recN) + { + switch (Sections) + { + case KB_CONST_SECTION: + Idx = KnowledgeBase.GetConstIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ConstOffsets[Idx].NamId; + if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) + { + String cname = ""; + if (cInfo->ConstName.Pos("_DV_") == 1) + { + char c = cInfo->ConstName[5]; + if (c > '9') + { + if (cInfo->ConstName[Len] == '_') + cname = cInfo->ConstName.SubString(5, Len - 5); + else + cname = cInfo->ConstName.SubString(5, Len - 4); + } + } + else + cname = cInfo->ConstName; + + recN = new InfoRec(_pos, ikData); + recN->kbIdx = Idx; + recN->SetName(cname); + recN->type = cInfo->TypeDef; + } + } + break; + case KB_TYPE_SECTION: + Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.TypeOffsets[Idx].NamId; + if (KnowledgeBase.GetTypeInfo(Idx, 0, tInfo)) + { + recN = new InfoRec(_pos, ikData); + recN->kbIdx = Idx; + recN->SetName(tInfo->TypeName); + } + } + break; + case KB_VAR_SECTION: + Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.VarOffsets[Idx].NamId; + if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) + { + recN = new InfoRec(_pos, ikData); + recN->kbIdx = Idx; + recN->SetName(vInfo->VarName); + recN->type = TrimTypeName(vInfo->TypeDef); + } + } + break; + case KB_RESSTR_SECTION: + Idx = KnowledgeBase.GetResStrIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ResStrOffsets[Idx].NamId; + if (KnowledgeBase.GetResStrInfo(Idx, 0, rsInfo)) + { + recN = new InfoRec(_pos, ikData); + recN->kbIdx = Idx; + recN->SetName(rsInfo->ResStrName); + recN->type = rsInfo->TypeDef; + } + } + break; + } + } + } + else + { + switch (Sections) + { + case KB_CONST_SECTION: + Idx = KnowledgeBase.GetConstIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ConstOffsets[Idx].NamId; + if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) + { + String cname = ""; + if (cInfo->ConstName.Pos("_DV_") == 1) + { + char c = cInfo->ConstName[5]; + if (c > '9') + { + if (cInfo->ConstName[Len] == '_') + cname = cInfo->ConstName.SubString(5, Len - 5); + else + cname = cInfo->ConstName.SubString(5, Len - 4); + } + } + else + cname = cInfo->ConstName; + + AddToBSSInfos(Adr, cname, cInfo->TypeDef); + } + } + break; + case KB_TYPE_SECTION: + Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.TypeOffsets[Idx].NamId; + if (KnowledgeBase.GetTypeInfo(Idx, 0, tInfo)) + { + AddToBSSInfos(Adr, tInfo->TypeName, ""); + } + } + break; + case KB_VAR_SECTION: + Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.VarOffsets[Idx].NamId; + if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) + { + AddToBSSInfos(Adr, vInfo->VarName, TrimTypeName(vInfo->TypeDef)); + } + } + break; + case KB_RESSTR_SECTION: + Idx = KnowledgeBase.GetResStrIdx(uses, fixupInfo.Name); + if (Idx != -1) + { + Idx = KnowledgeBase.ResStrOffsets[Idx].NamId; + if (KnowledgeBase.GetResStrInfo(Idx, 0, rsInfo)) + { + AddToBSSInfos(Adr, rsInfo->ResStrName, rsInfo->TypeDef); + } + } + break; + } + } + } + } + if (uses) delete[] uses; + } +} +//--------------------------------------------------------------------------- +int DelphiVersions[] = {2, 3, 4, 5, 6, 7, 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014, 0}; + +int __fastcall TFMain_11011981::GetDelphiVersion() +{ + WORD moduleID; + int idx, num, pos, version; + DWORD unitsTab, iniAdr, finAdr, vmtAdr, adr; + DWORD TControlInstSize; + PInfoRec recN; + String name, KBFileName; + MKnowledgeBase SysKB; + MProcInfo aInfo; + MProcInfo* pInfo = &aInfo; + + if (IsExtendedInitTab(&unitsTab))//>=2010 + { + KBFileName = AppDir + "syskb2014.bin"; + if (SysKB.Open(KBFileName.c_str())) + { + moduleID = SysKB.GetModuleID("System"); + if (moduleID != 0xFFFF) + { + //Find index of function "StringCopy" in this module + idx = SysKB.GetProcIdx(moduleID, "StringCopy"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return 2014; + } + } + } + SysKB.Close(); + } + KBFileName = AppDir + "syskb2013.bin"; + if (SysKB.Open(KBFileName.c_str())) + { + moduleID = SysKB.GetModuleID("System"); + if (moduleID != 0xFFFF) + { + //Find index of function "@FinalizeResStrings" in this module + idx = SysKB.GetProcIdx(moduleID, "@FinalizeResStrings"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return 2013; + } + } + } + SysKB.Close(); + } + + KBFileName = AppDir + "syskb2012.bin"; + if (SysKB.Open(KBFileName.c_str())) + { + moduleID = SysKB.GetModuleID("System"); + if (moduleID != 0xFFFF) + { + //Find index of function "@InitializeControlWord" in this module + idx = SysKB.GetProcIdx(moduleID, "@InitializeControlWord"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return 2012; + } + } + } + SysKB.Close(); + } + + KBFileName = AppDir + "syskb2011.bin"; + if (SysKB.Open(KBFileName.c_str())) + { + moduleID = SysKB.GetModuleID("System"); + if (moduleID != 0xFFFF) + { + //Find index of function "ErrorAt" in this module + idx = SysKB.GetProcIdx(moduleID, "ErrorAt"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return 2011; + } + } + } + SysKB.Close(); + } + return 2010; + } + + TControlInstSize = 0; + //Ïðîáóåì äëÿ íà÷àëà êàê â DeDe (Èùåì òèï TControl) + for (int n = 0; n < TotalSize - 14; n += 4) + { + if (Image[n] == 7 && Image[n + 1] == 8 && + Image[n + 2] == 'T' && Image[n + 3] == 'C' && + Image[n + 4] == 'o' && Image[n + 5] == 'n' && + Image[n + 6] == 't' && Image[n + 7] == 'r' && + Image[n + 8] == 'o' && Image[n + 9] == 'l') + { + //Ïîñëå òèïà äîëæåí ñëåäîâàòü óêàçàòåëü íà òàáëèöó VMT (0) + vmtAdr = *((DWORD*)(Image + n + 10)); + if (IsValidImageAdr(vmtAdr)) + { + //Ïðîâåðÿåì ñìåùåíèå -0x18 + TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x18)); + if (TControlInstSize == 0xA8) return 2; + //Ïðîâåðÿåì ñìåùåíèå -0x1C + TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x1C)); + if (TControlInstSize == 0xB0 || TControlInstSize == 0xB4) return 3; + //Ïðîâåðÿåì ñìåùåíèå -0x28 + TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x28)); + if (TControlInstSize == 0x114) return 4; + if (TControlInstSize == 0x120) return 5; + if (TControlInstSize == 0x15C) //6 èëè 7 + { + DWORD TFormInstSize = 0; + //Èùåì òèï TForm (âûáîð ìåæäó âåðñèåé 6 è 7) + for (int m = 0; m < TotalSize - 11; m += 4) + { + if (Image[m] == 7 && Image[m + 1] == 5 && Image[m + 2] == 'T' && + Image[m + 3] == 'F' && Image[m + 4] == 'o' && + Image[m + 5] == 'r' && Image[m + 6] == 'm') + { + //Ïîñëå òèïà äîëæåí ñëåäîâàòü óêàçàòåëü íà òàáëèöó VMT (0) + vmtAdr = *((DWORD*)(Image + m + 7)); + if (IsValidImageAdr(vmtAdr)) + { + //Ïðîâåðÿåì ñìåùåíèå -0x28 + TFormInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x28)); + if (TFormInstSize == 0x2F0) return 6; + if (TFormInstSize == 0x2F8) return 7; + } + } + } + break; + } + if (TControlInstSize == 0x164) return 2005; + if (TControlInstSize == 0x190) break; //2006 èëè 2007 + //Ïðîâåðÿåì ñìåùåíèå -0x34 + TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x34)); + if (TControlInstSize == 0x1A4) return 2009; + //if (TControlInstSize == 0x1AC) return 2010; + } + } + } + //Îñòàâøèåñÿ âàðèàíòû ïðîâåðÿåì ÷åðåç áàçó çíàíèé + for (int v = 0; DelphiVersions[v]; v++) + { + version = DelphiVersions[v]; + if (TControlInstSize == 0x190 && version != 2006 && version != 2007) continue; + KBFileName = AppDir + "syskb" + version + ".bin"; + if (SysKB.Open(KBFileName.c_str())) + { + moduleID = SysKB.GetModuleID("System"); + if (moduleID != 0xFFFF) + { + //Èùåì èíäåêñ ôóíêöèè "System" â äàííîì ìîäóëå + idx = SysKB.GetProcIdx(moduleID, "System"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + if (version == 4 || version == 5) + { + idx = SysKB.GetProcIdx(moduleID, "@HandleAnyException"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return version; + } + } + } + else if (version == 2006 || version == 2007) + { + idx = SysKB.GetProcIdx(moduleID, "GetObjectClass"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return version; + } + } + } + else if (version == 2009 || version == 2010) + { + //Èùåì èíäåêñ ôóíêöèè "@Halt0" â äàííîì ìîäóëå + idx = SysKB.GetProcIdx(moduleID, "@Halt0"); + if (idx != -1) + { + pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); + pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + SysKB.Close(); + return version; + } + } + } + else + { + SysKB.Close(); + return version; + } + } + } + } + SysKB.Close(); + } + } + //Analyze VMTs (if exists) + version = -1; + for (int n = 0; n < CodeSize; n += 4) + { + vmtAdr = *((DWORD*)(Code + n)); //Points to vmt0 (cVmtSelfPtr) + //cVmtSelfPtr + if (IsValidCodeAdr(vmtAdr)) + { + if (Pos2Adr(n) == vmtAdr - 0x34) + { + //cVmtInitTable + adr = *((DWORD*)(Code + n + 4)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtTypeInfo + adr = *((DWORD*)(Code + n + 8)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtFieldTable + adr = *((DWORD*)(Code + n + 12)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtMethodTable + adr = *((DWORD*)(Code + n + 16)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtDynamicTable + adr = *((DWORD*)(Code + n + 20)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtClassName + adr = *((DWORD*)(Code + n + 24)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtInstanceSize + adr = *((DWORD*)(Code + n + 28)); + if (!adr || IsValidCodeAdr(adr)) continue; + version = Pos2Adr(n) - vmtAdr; + break; + } + else if (Pos2Adr(n) == vmtAdr - 0x40 || Pos2Adr(n) == vmtAdr - 0x4C || Pos2Adr(n) == vmtAdr - 0x58) + { + //cVmtIntfTable + adr = *((DWORD*)(Code + n + 4)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtAutoTable + adr = *((DWORD*)(Code + n + 8)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtInitTable + adr = *((DWORD*)(Code + n + 12)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtTypeInfo + adr = *((DWORD*)(Code + n + 16)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtFieldTable + adr = *((DWORD*)(Code + n + 20)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtMethodTable + adr = *((DWORD*)(Code + n + 24)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtDynamicTable + adr = *((DWORD*)(Code + n + 28)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtClassName + adr = *((DWORD*)(Code + n + 32)); + if (adr && !IsValidCodeAdr(adr)) continue; + //cVmtInstanceSize + adr = *((DWORD*)(Code + n + 36)); + if (!adr || IsValidCodeAdr(adr)) continue; + version = Pos2Adr(n) - vmtAdr; + break; + } + } + } + if (version == -0x34) return 2; + if (version == -0x40) return 3; + if (version == -0x58) return 2009; + /* + //Check that system is in external rtl + num = *((DWORD*)(Code + unitsTab - 8)); + for (int n = 0; n < num; n++, unitsTab += 8) + { + iniAdr = *((DWORD*)(Code + unitsTab)); + if (iniAdr && IsValidImageAdr(iniAdr) && IsFlagSet(cfImport, Adr2Pos(iniAdr))) + { + recN = GetInfoRec(iniAdr); + pos = recN->name.Pos("."); + if (pos && SameText(recN->name.SubString(pos + 1, 22), "@System@Initialization")) + { + name = recN->name.SubString(1, pos - 1); + if (SameText(name, "rtl120")) return 2009; + } + } + finAdr = *((DWORD*)(Code + unitsTab + 4)); + if (finAdr && IsValidImageAdr(finAdr) && IsFlagSet(cfImport, Adr2Pos(finAdr)))) + { + recN = GetInfoRec(finAdr); + pos = recN->name.Pos("."); + if (pos) + { + name = recN->name.SubString(1, pos - 1); + } + } + } + */ + //as + //try to find the Delphi version based on imported delphi bpls.... (if any) + typedef struct + { + char* versionVcl; //digital part of version present in vclXXX file name + char* versionRtl; //digital part of version present in rtlXXX file name + char* versionString; //full string of vcl/rtl bpl from file properties + int versionForIdr; //value that returns to caller + } DelphiBplVersionRec; + + const DelphiBplVersionRec delphiBplVer[] = {//Borland + {"vcl30.dpl", "", "3.0.5.53" , 3 }, //no rtl30.dpl! + {"vcl40.bpl", "", "4.0.5.38" , 4 }, //no rtl40.bpl! + {"vcl60.bpl", "rtl60.bpl", "6.0.6.240" , 6 }, + {"vcl60.bpl", "rtl60.bpl", "6.0.6.243" , 6 }, + {"vcl70.bpl", "rtl70.bpl", "7.0.4.453" , 7 }, + {"vcl90.bpl", "rtl90.bpl", "9.0.1761.24408", 2005}, + {"vcl100.bpl", "rtl100.bpl","10.0.2151.25345", 2006}, //SP2 + {"vcl100.bpl", "rtl100.bpl","11.0.2627.5503", 2007}, //CodeGear + {"vcl100.bpl", "rtl100.bpl","11.0.2902.10471", 2007}, + {"vcl120.bpl", "rtl120.bpl","12.0.3210.17555", 2009}, //Embarcadero + {"", "", "", 0} + }; + + String rtlBplName, vclBplName, rtlBpl, vclBpl; + + for (int n = 0; n < ImpModuleList->Count; n++) + { + if (ImpModuleList->Strings[n].SubString(1,3).LowerCase() == "rtl") + rtlBpl = ImpModuleList->Strings[n].LowerCase(); + else if (ImpModuleList->Strings[n].SubString(1,3).LowerCase() == "vcl") + vclBpl = ImpModuleList->Strings[n].LowerCase(); + + if (rtlBpl != "" && vclBpl != "") break; + } + + // or (||) is here because Delphi3 and 4 do not have rtl... + if (rtlBpl != "" || vclBpl != "") + { + for (int i = 0; delphiBplVer[i].versionForIdr; ++i) + { + rtlBplName = String(delphiBplVer[i].versionRtl); + vclBplName = String(delphiBplVer[i].versionVcl); + + if (vclBplName != vclBpl) continue; + + //if we found something - lets continue the analysis + //here we have two cases + // (i) bpl are near the input Delphi target or + // (ii) it was installed into system dir...(or any dir in %PATH% !) + + String srcPath = ExtractFilePath(SourceFile); + String rtlFile = !rtlBplName.IsEmpty() ? srcPath+rtlBplName : rtlBplName; + String vclFile = srcPath+vclBplName; + + if (!FileExists(vclFile)) + { + //we'll not look into windows\\system32 only... + //instead we leave path as no path -> system will scan for us + //in all the %PATH% directories (when doing LoadLibrary)! + rtlFile = rtlBplName; + vclFile = vclBplName; + } + + //check the export of bpl - it must have 2 predefined functions + if (!((rtlFile == "" || IsBplByExport(rtlFile.c_str())) && IsBplByExport(vclFile.c_str()))) + { + ShowMessage("Input file imports Delphi system packages (" + + rtlFile + ", " + vclFile + ")." + "\r\nIn order to figure out the version, please put it nearby"); + break; + } + + String rtlBplVersion = GetModuleVersion(rtlFile); + String vclBplVersion = GetModuleVersion(vclFile); + //hack for D3 and 4 + if (rtlBplVersion == "") rtlBplVersion = vclBplVersion; + if (rtlBplVersion == vclBplVersion && rtlBplVersion == String(delphiBplVer[i].versionString)) + return delphiBplVer[i].versionForIdr; + } + } + if (version == -0x4C) return 1; + //here we failed to find the version.....sorry + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::InitSysProcs() +{ + int Idx, pos; + MProcInfo aInfo, *pInfo; + + SysProcsNum = 0; + WORD moduleID = KnowledgeBase.GetModuleID("System"); + for (int n = 0; SysProcs[n].name; n++) + { + Idx = KnowledgeBase.GetProcIdx(moduleID, SysProcs[n].name); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, &aInfo); + if (SysProcs[n].impAdr) + { + StrapProc(Adr2Pos(SysProcs[n].impAdr), Idx, pInfo, false, 6); + } + else + { + pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + PInfoRec recN = new InfoRec(pos, ikRefine); + recN->SetName(SysProcs[n].name); + StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); + } + } + } + } + SysProcsNum++; + } + moduleID = KnowledgeBase.GetModuleID("SysInit"); + for (int n = 0; SysInitProcs[n].name; n++) + { + Idx = KnowledgeBase.GetProcIdx(moduleID, SysInitProcs[n].name); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, &aInfo); + if (SysInitProcs[n].impAdr) + { + StrapProc(Adr2Pos(SysInitProcs[n].impAdr), Idx, pInfo, false, 6); + } + pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); + if (pos != -1) + { + PInfoRec recN = new InfoRec(pos, ikRefine); + recN->SetName(SysInitProcs[n].name); + StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); + if (n == 1) SourceIsLibrary = true; + } + } + } + SysProcsNum++; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::SetVmtConsts(int version) +{ + switch (version) + { + case 2: + cVmtSelfPtr = -0x34; //??? (=0???) + cVmtInitTable = -0x30; + cVmtTypeInfo = -0x2C; + cVmtFieldTable = -0x28; + cVmtMethodTable = -0x24; + cVmtDynamicTable = -0x20; + cVmtClassName = -0x1C; + cVmtInstanceSize = -0x18; + cVmtParent = -0x14; + cVmtDefaultHandler = -0x10; + cVmtNewInstance = -0xC; + cVmtFreeInstance = -8; + cVmtDestroy = -4; + break; + case 3: + cVmtSelfPtr = -0x40; + cVmtIntfTable = -0x3C; + cVmtAutoTable = -0x38; + cVmtInitTable = -0x34; + cVmtTypeInfo = -0x30; + cVmtFieldTable = -0x2C; + cVmtMethodTable = -0x28; + cVmtDynamicTable = -0x24; + cVmtClassName = -0x20; + cVmtInstanceSize = -0x1C; + cVmtParent = -0x18; + cVmtSafeCallException = -0x14; + cVmtDefaultHandler = -0x10; + cVmtNewInstance = -0xC; + cVmtFreeInstance = -8; + cVmtDestroy = -4; + break; + case 4: + case 5: + case 6: + case 7: + case 2005: + case 2006: + case 2007: + cVmtSelfPtr = -0x4C; + cVmtIntfTable = -0x48; + cVmtAutoTable = -0x44; + cVmtInitTable = -0x40; + cVmtTypeInfo = -0x3C; + cVmtFieldTable = -0x38; + cVmtMethodTable = -0x34; + cVmtDynamicTable = -0x30; + cVmtClassName = -0x2C; + cVmtInstanceSize = -0x28; + cVmtParent = -0x24; + cVmtSafeCallException = -0x20; + cVmtAfterConstruction = -0x1C; + cVmtBeforeDestruction = -0x18; + cVmtDispatch = -0x14; + cVmtDefaultHandler = -0x10; + cVmtNewInstance = -0xC; + cVmtFreeInstance = -8; + cVmtDestroy = -4; + break; + case 2009: + case 2010: + cVmtSelfPtr = -0x58; + cVmtIntfTable = -0x54; + cVmtAutoTable = -0x50; + cVmtInitTable = -0x4C; + cVmtTypeInfo = -0x48; + cVmtFieldTable = -0x44; + cVmtMethodTable = -0x40; + cVmtDynamicTable = -0x3C; + cVmtClassName = -0x38; + cVmtInstanceSize = -0x34; + cVmtParent = -0x30; + cVmtEquals = -0x2C; + cVmtGetHashCode = -0x28; + cVmtToString = -0x24; + cVmtSafeCallException = -0x20; + cVmtAfterConstruction = -0x1C; + cVmtBeforeDestruction = -0x18; + cVmtDispatch = -0x14; + cVmtDefaultHandler = -0x10; + cVmtNewInstance = -0xC; + cVmtFreeInstance = -8; + cVmtDestroy = -4; + break; + case 2011: + case 2012: + case 2013: + case 2014: + cVmtSelfPtr = -0x58; + cVmtIntfTable = -0x54; + cVmtAutoTable = -0x50; + cVmtInitTable = -0x4C; + cVmtTypeInfo = -0x48; + cVmtFieldTable = -0x44; + cVmtMethodTable = -0x40; + cVmtDynamicTable = -0x3C; + cVmtClassName = -0x38; + cVmtInstanceSize = -0x34; + cVmtParent = -0x30; + cVmtEquals = -0x2C; + cVmtGetHashCode = -0x28; + cVmtToString = -0x24; + cVmtSafeCallException = -0x20; + cVmtAfterConstruction = -0x1C; + cVmtBeforeDestruction = -0x18; + cVmtDispatch = -0x14; + cVmtDefaultHandler = -0x10; + cVmtNewInstance = -0xC; + cVmtFreeInstance = -8; + cVmtDestroy = -4; + //VmtQueryInterface = 0; + //VmtAddRef = 4; + //VmtRelease = 8; + //VmtCreateObject = 0xC; + break; + } +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::IsUnitExist(String Name) +{ + for (int n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + if (recU->names->IndexOf(Name) != -1) return true; + } + return false; +} +//--------------------------------------------------------------------------- +PUnitRec __fastcall TFMain_11011981::GetUnit(DWORD Adr) +{ + PUnitRec _res; + + CrtSection->Enter(); + _res = 0; + for (int n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + if (Adr >= recU->fromAdr && Adr < recU->toAdr) _res = recU; + } + CrtSection->Leave(); + return _res; +} +//--------------------------------------------------------------------------- +String __fastcall TFMain_11011981::GetUnitName(PUnitRec recU) +{ + if (recU) + { + if (recU->names->Count == 1) + return recU->names->Strings[0]; + else + return "_Unit" + String(recU->iniOrder); + } + return ""; +} +//--------------------------------------------------------------------------- +String __fastcall TFMain_11011981::GetUnitName(DWORD Adr) +{ + int n; + String Result = ""; + + PUnitRec recU = GetUnit(Adr); + if (recU) + { + for (n = 0; n < recU->names->Count; n++) + { + if (n) Result += ", "; + Result += recU->names->Strings[n]; + } + } + return Result; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::SetUnitName(PUnitRec recU, String name) +{ + if (recU && recU->names->IndexOf(name) == -1) + recU->names->Add(name); +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::InOneUnit(DWORD Adr1, DWORD Adr2) +{ + for (int n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + if (Adr1 >= recU->fromAdr && Adr1 < recU->toAdr && + Adr2 >= recU->fromAdr && Adr2 < recU->toAdr) return true; + } + return false; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::GetSegmentNo(DWORD Adr) +{ + for (int n = 0; n < SegmentList->Count; n++) + { + PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; + if (segInfo->Start <= Adr && Adr < segInfo->Start + segInfo->Size) return n; + } + return -1; +} +//--------------------------------------------------------------------------- +DWORD __fastcall FollowInstructions(DWORD fromAdr, DWORD toAdr) +{ + int instrLen; + int fromPos = Adr2Pos(fromAdr); + int curPos = fromPos; + DWORD curAdr = fromAdr; + DISINFO DisInfo; + + while (1) + { + if (curAdr >= toAdr) break; + if (IsFlagSet(cfInstruction, curPos)) break; + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + if (!instrLen) break; + SetFlag(cfInstruction, curPos); + } + return curAdr; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::EstimateProcSize(DWORD fromAdr) +{ + BYTE op; + int row, num, instrLen, instrLen1, instrLen2, Pos; + int fromPos = Adr2Pos(fromAdr); + int curPos = fromPos; + DWORD curAdr = fromAdr; + DWORD lastAdr = 0; + DWORD Adr, Adr1, lastMovAdr = 0; + PInfoRec recN; + DISINFO DisInfo; + + int outRows = MAX_DISASSEMBLE; + if (IsFlagSet(cfImport, fromPos)) outRows = 1; + + for (row = 0; row < outRows; row++) + { + //Exception table + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + curPos += 4 + 8*num; curAdr += 4 + 8*num; + continue; + } + + BYTE b1 = Code[curPos]; + BYTE b2 = Code[curPos + 1]; + if (!b1 && !b2 && !lastAdr) break; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) break; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + //Code + SetFlags(cfCode, curPos, instrLen); + //Instruction begin + SetFlag(cfInstruction, curPos); + + op = Disasm.GetOp(DisInfo.Mnem); + + if (curAdr >= lastAdr) lastAdr = 0; + + if (op == OP_JMP) + { + if (curAdr == fromAdr) + { + curAdr += instrLen; + break; + } + if (DisInfo.OpType[0] == otMEM) + { + if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) + { + curAdr += instrLen; + break; + } + } + if (DisInfo.OpType[0] == otIMM) + { + Adr = DisInfo.Immediate; + if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) + { + curAdr += instrLen; + break; + } + if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) + { + curAdr += instrLen; + break; + } + if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) + { + curAdr += instrLen; + break; + } + } + } + //End of procedure + if (DisInfo.Ret)// && (!lastAdr || curAdr == lastAdr)) + { + if (!IsFlagSet(cfLoc, Pos + instrLen)) + { + curAdr += instrLen; + break; + } + } + + if (op == OP_MOV) lastMovAdr = DisInfo.Offset; + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + if (!IsValidCodeAdr(DisInfo.Offset)) + { + curAdr += instrLen; + break; + } + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Àäðåñ òàáëèöû - ïîñëåäíèå 4 áàéòà èíñòðóêöèè + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Àíàëèçèðóåì ïðîìåæóòîê íà ïðåäìåò òàáëèöû cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //Åñëè åñòü cTblAdr, ïðîïóñêàåì ýòó òàáëèöó + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + Pos += CNum; Adr += CNum; + } + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidImageAdr(Adr1) || Adr1 < fromAdr) break; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } + + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + //if (!instrLen1) return Size; + + recN = GetInfoRec(DisInfo.Immediate); + if (recN) + { + if (recN->SameName("@HandleFinally")) + { + //jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + /* + //@2 + Adr1 = DisInfo.Immediate - 4; + Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); + if (Adr > lastAdr) lastAdr = Adr; + */ + } + else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //Set cfETable to output data correctly + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Pos += 4; + //dd offset ExceptionProc + Pos += 4; + } + } + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + if (b1 == 0xEB || //short relative abs jmp or cond jmp + (b1 >= 0x70 && b1 <= 0x7F) || + (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) + { + Adr = DisInfo.Immediate; + if (IsValidImageAdr(Adr)) + { + SetFlag(cfLoc, Adr2Pos(Adr)); + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + if (b1 == 0xE9) //relative abs jmp or cond jmp + { + Adr = DisInfo.Immediate; + if (IsValidImageAdr(Adr)) + { + SetFlag(cfLoc, Adr2Pos(Adr)); + recN = GetInfoRec(Adr); + if (!recN && Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + if (DisInfo.Call) + { + Adr = DisInfo.Immediate; Pos = Adr2Pos(Adr); + if (IsValidImageAdr(Adr)) + { + if (Pos >= 0) + { + SetFlag(cfLoc, Pos); + recN = GetInfoRec(Adr); + if (recN && recN->SameName("@Halt0")) + { + if (fromAdr == EP && !lastAdr) break; + } + } + /* + //Call is inside procedure (may be embedded or filled by data) + if (lastAdr && Adr > fromAdr && Adr <= lastAdr) + { + if (!IsFlagSet(cfInstruction, Pos)) + { + curAdr = Adr; + curPos = Pos; + } + else + { + curPos += instrLen; + curAdr += instrLen; + } + } + */ + } + } + curPos += instrLen; curAdr += instrLen; + } + return curAdr - fromAdr; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::GetUnits2(String dprName) +{ + int instrLen, iniProcSize, pos, num, start, n; + DWORD iniAdr; + DWORD curAdr = EP; + DWORD curPos = Adr2Pos(curAdr); + PUnitRec recU; + DISINFO DisInfo; + + //Èùåì ïåðâóþ èíñòðóêöèþ call = @InitExe + n = 0; + while (1) + { + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) return num; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + if (DisInfo.Call) n++; + if (n == 2) break; + curPos += instrLen; + curAdr += instrLen; + } + //×èòàåì ñïèñîê âûçîâîâ (ïðîöåäóðû èíèöèàëèçàöèè) + int no = 1; + for (num = 0;; num++) + { + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) return num; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + if (!DisInfo.Call) break; + iniAdr = DisInfo.Immediate; + iniProcSize = EstimateProcSize(iniAdr); + + recU = new UnitRec; + recU->trivial = false; + recU->trivialIni = false; + recU->trivialFin = true; + recU->kb = false; + recU->names = new TStringList; + + recU->fromAdr = 0; + recU->toAdr = 0; + recU->matchedPercent = 0.0; + recU->iniOrder = no; no++; + + recU->toAdr = (iniAdr + iniProcSize + 3) & 0xFFFFFFFC; + + recU->finadr = 0; + recU->finSize = 0; + recU->iniadr = iniAdr; + recU->iniSize = iniProcSize; + + pos = Adr2Pos(iniAdr); + SetFlag(cfProcStart, pos); + PInfoRec recN = GetInfoRec(iniAdr); + if (!recN) recN = new InfoRec(pos, ikProc); + recN->procInfo->procSize = iniProcSize; + + Units->Add((void*)recU); + + curPos += instrLen; + curAdr += instrLen; + } + + start = CodeBase; + num = Units->Count; + for (int i = 0; i < num; i++) + { + recU = (PUnitRec)Units->Items[i]; + recU->fromAdr = start; + start = recU->toAdr; + //Last Unit has program name + if (i == num - 1) + { + recU->toAdr = CodeBase + CodeSize; + SetUnitName(recU, dprName); + } + } + + return num; +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::IsExtendedInitTab(DWORD* unitsTab) +{ + int i, num, pos, n; + DWORD adr, initTable, iniAdr, finAdr; + + *unitsTab = 0; + for (i = 0; i < ((TotalSize - 4) & (-4)); i += 4) + { + initTable = *((DWORD*)(Image + i)); + if (initTable == CodeBase + i + 4) + { + num = *((DWORD*)(Image + i - 4)); + if (num <= 0 || num > 10000) continue; + + pos = *unitsTab = i + 4; + for (n = 0; n < num; n++, pos += 8) + { + iniAdr = *((DWORD*)(Image + pos)); + if (iniAdr) + { + if (!IsValidImageAdr(iniAdr)) + { + *unitsTab = 0; + break; + } + } + finAdr = *((DWORD*)(Image + pos + 4)); + if (finAdr) + { + if (!IsValidImageAdr(finAdr)) + { + *unitsTab = 0; + break; + } + } + } + if (*unitsTab) break; + } + } + if (*unitsTab) return false; + + //May be D2010 + *unitsTab = 0; + for (i = 0; i < ((TotalSize - 20) & (-4)); i += 4) + { + initTable = *((DWORD*)(Image + i)); + if (initTable == CodeBase + i + 20) + { + num = *((DWORD*)(Image + i - 4)); + if (num <= 0 || num > 10000) continue; + + pos = *unitsTab = i + 20; + for (n = 0; n < num; n++, pos += 8) + { + iniAdr = *((DWORD*)(Image + pos)); + if (iniAdr) + { + if (!IsValidImageAdr(iniAdr)) + { + *unitsTab = 0; + break; + } + } + finAdr = *((DWORD*)(Image + pos + 4)); + if (finAdr) + { + if (!IsValidImageAdr(finAdr)) + { + *unitsTab = 0; + break; + } + } + } + if (*unitsTab) break; + } + } + if (*unitsTab) return true; + + return false; +} +//--------------------------------------------------------------------------- +DWORD __fastcall TFMain_11011981::EvaluateInitTable(BYTE* Data, DWORD Size, DWORD Base) +{ + int i, num, pos, unitsPos = 0, n; + int curPos, instrLen; + DWORD initTable, result, iniAdr, finAdr, maxAdr = 0; + DWORD endAdr, curAdr, dd, modTable; + DISINFO disInfo; + + for (i = 0; i < ((Size - 4) & (-4)); i += 4) + { + initTable = result = *((DWORD*)(Data + i)); + if (initTable == Base + i + 4) + { + num = *((DWORD*)(Data + i - 4)); + if (num <= 0 || num > 10000) continue; + pos = unitsPos = i + 4; + for (n = 0; n < num; n++, pos += 8) + { + iniAdr = *((DWORD*)(Data + pos)); + if (iniAdr) + { + if (iniAdr < Base || iniAdr >= Base + Size)//!IsValidImageAdr(iniAdr)) + { + unitsPos = 0; + break; + } + else if (iniAdr > maxAdr) + { + maxAdr = iniAdr; + } + } + finAdr = *((DWORD*)(Data + pos + 4)); + if (finAdr) + { + if (finAdr < Base || finAdr >= Base + Size)//!IsValidImageAdr(finAdr)) + { + unitsPos = 0; + break; + } + else if (finAdr > maxAdr) + { + maxAdr = finAdr; + } + } + result += 8; + } + if (unitsPos) break; + } + } + if (maxAdr > result) result = (maxAdr + 3) & (-4); + + if (unitsPos) return initTable - 8; + + //May be D2010 + maxAdr = 0; + for (i = 0; i < ((Size - 20) & (-4)); i += 4) + { + initTable = result = *((DWORD*)(Data + i)); + if (initTable == Base + i + 20) + { + num = *((DWORD*)(Data + i - 4)); + if (num <= 0 || num > 10000) continue; + + pos = unitsPos = i + 20; + for (n = 0; n < num; n++, pos += 8) + { + iniAdr = *((DWORD*)(Data + pos)); + if (iniAdr) + { + if (iniAdr < Base || iniAdr >= Base + Size) + { + unitsPos = 0; + break; + } + else if (iniAdr > maxAdr) + { + if (*((DWORD*)(Data + Adr2Pos(iniAdr)))) maxAdr = iniAdr; + } + } + finAdr = *((DWORD*)(Data + pos + 4)); + if (finAdr) + { + if (finAdr < Base || finAdr >= Base + Size) + { + unitsPos = 0; + break; + } + else if (finAdr > maxAdr) + { + if (*((DWORD*)(Data + Adr2Pos(finAdr)))) maxAdr = finAdr; + } + } + result += 8; + } + if (unitsPos) break; + } + } + if (maxAdr > result) result = (maxAdr + 3) & (-4); + + if (unitsPos) return initTable - 24; + + //May be BCB + curAdr = EP; curPos = Adr2Pos(curAdr); + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &disInfo, 0); + dd = *((DWORD*)disInfo.Mnem); + if (dd == 'pmj') + { + curAdr = disInfo.Immediate; curPos = Adr2Pos(curAdr); + while (1) + { + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &disInfo, 0); + dd = *((DWORD*)disInfo.Mnem); + if (dd == 'pmj') break; + if (dd == 'hsup' && disInfo.OpType[0] == otIMM && disInfo.Immediate) + { + modTable = disInfo.Immediate; + if (IsValidImageAdr(modTable)) + { + pos = unitsPos = Adr2Pos(modTable); + iniAdr = initTable = *((DWORD*)(Image + pos)); + if (iniAdr < Base || iniAdr >= Base + Size) unitsPos = 0; + endAdr = *((DWORD*)(Image + pos + 4));//ini table and + if (endAdr < Base || endAdr >= Base + Size) unitsPos = 0; + finAdr = *((DWORD*)(Image + pos + 8)); + if (finAdr < Base || finAdr >= Base + Size) unitsPos = 0; + endAdr = *((DWORD*)(Image + pos + 12));//fin table end + if (endAdr < Base || endAdr >= Base + Size) unitsPos = 0; + break; + } + } + curAdr += instrLen; curPos += instrLen; + } + if (unitsPos) + { + BCB = true; + return initTable; + } + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::GetUnits(String dprName) +{ + BYTE len; + char *b, *e; + int n, i, no, unitsPos = 0, start, spos, pos, iniProcSize, finProcSize, unitsNum = 0; + int typesNum, units1Num, typesTable, units1Table; //For D2010 + DWORD initTable, iniAdr, finAdr, unitsTabEnd, toAdr; + PUnitRec recU; + PInfoRec recN; + + if (DelphiVersion >= 2010) + { + for (i = 0; i < ((TotalSize - 20) & (-4)); i += 4) + { + initTable = *((DWORD*)(Image + i)); + if (initTable == CodeBase + i + 20) + { + unitsNum = *((DWORD*)(Image + i - 4)); + if (unitsNum <= 0 || unitsNum > 10000) continue; + + pos = unitsPos = i + 20; + for (n = 0; n < unitsNum; n++, pos += 8) + { + iniAdr = *((DWORD*)(Image + pos)); + if (iniAdr && !IsValidImageAdr(iniAdr)) + { + unitsPos = 0; + break; + } + finAdr = *((DWORD*)(Image + pos + 4)); + if (finAdr && !IsValidImageAdr(finAdr)) + { + unitsPos = 0; + break; + } + } + if (unitsPos) break; + } + } + } + else + { + for (i = 0; i < ((CodeSize - 4) & (-4)); i += 4) + { + initTable = *((DWORD*)(Image + i)); + if (initTable == CodeBase + i + 4) + { + unitsNum = *((DWORD*)(Image + i - 4)); + if (unitsNum <= 0 || unitsNum > 10000) continue; + + pos = unitsPos = i + 4; + for (n = 0; n < unitsNum; n++, pos += 8) + { + iniAdr = *((DWORD*)(Image + pos)); + if (iniAdr && !IsValidImageAdr(iniAdr)) + { + unitsPos = 0; + break; + } + finAdr = *((DWORD*)(Image + pos + 4)); + if (finAdr && !IsValidImageAdr(finAdr)) + { + unitsPos = 0; + break; + } + } + if (unitsPos) break; + } + } + } + //if (!unitsPos) return 0; + + if (!unitsPos) + { + unitsNum = 1; + recU = new UnitRec; + recU->trivial = false; + recU->trivialIni = true; + recU->trivialFin = true; + recU->kb = false; + recU->names = new TStringList; + + recU->fromAdr = CodeBase; + recU->toAdr = CodeBase + TotalSize; + recU->matchedPercent = 0.0; + recU->iniOrder = 1; + + recU->finadr = 0; + recU->finSize = 0; + recU->iniadr = 0; + recU->iniSize = 0; + Units->Add((void*)recU); + return unitsNum; + } + + unitsTabEnd = initTable + 8 * unitsNum; + if (DelphiVersion >= 2010) + { + initTable -= 24; + SetFlags(cfData, Adr2Pos(initTable), 8*unitsNum + 24); + typesNum = *((int*)(Image + Adr2Pos(initTable + 8))); + typesTable = *((int*)(Image + Adr2Pos(initTable + 12))); + SetFlags(cfData, Adr2Pos(typesTable), 4*typesNum); + units1Num = *((int*)(Image + Adr2Pos(initTable + 16))); + units1Table = *((int*)(Image + Adr2Pos(initTable + 20))); + spos = pos = Adr2Pos(units1Table); + for (i = 0; i < units1Num; i++) + { + len = *(Image + pos); + pos += len + 1; + } + SetFlags(cfData, Adr2Pos(units1Table), pos - spos); + } + else + { + initTable -= 8; + SetFlags(cfData, Adr2Pos(initTable), 8*unitsNum + 8); + } + + for (i = 0, no = 1; i < unitsNum; i++, unitsPos += 8) + { + iniAdr = *((DWORD*)(Image + unitsPos)); + finAdr = *((DWORD*)(Image + unitsPos + 4)); + + if (!iniAdr && !finAdr) continue; + + if (iniAdr && *((DWORD*)(Image + Adr2Pos(iniAdr))) == 0) continue; + if (finAdr && *((DWORD*)(Image + Adr2Pos(finAdr))) == 0) continue; + + //MAY BE REPEATED ADRESSES!!! + bool found = false; + for (n = 0; n < Units->Count; n++) + { + recU = (PUnitRec)Units->Items[n]; + if (recU->iniadr == iniAdr && recU->finadr == finAdr) + { + found = true; + break; + } + } + if (found) continue; + + if (iniAdr) + iniProcSize = EstimateProcSize(iniAdr); + else + iniProcSize = 0; + + if (finAdr) + finProcSize = EstimateProcSize(finAdr); + else + finProcSize = 0; + + toAdr = 0; + if (iniAdr && iniAdr < unitsTabEnd) + { + if (iniAdr >= finAdr + finProcSize) + toAdr = (iniAdr + iniProcSize + 3) & 0xFFFFFFFC; + if (finAdr >= iniAdr + iniProcSize) + toAdr = (finAdr + finProcSize + 3) & 0xFFFFFFFC; + } + else if (finAdr) + { + toAdr = (finAdr + finProcSize + 3) & 0xFFFFFFFC; + } + + if (!toAdr) + { + if (Units->Count > 0) continue; + toAdr = CodeBase + CodeSize; + } + + recU = new UnitRec; + recU->trivial = false; + recU->trivialIni = true; + recU->trivialFin = true; + recU->kb = false; + recU->names = new TStringList; + + recU->fromAdr = 0; + recU->toAdr = toAdr; + recU->matchedPercent = 0.0; + recU->iniOrder = no; no++; + + recU->finadr = finAdr; + recU->finSize = finProcSize; + recU->iniadr = iniAdr; + recU->iniSize = iniProcSize; + + if (iniAdr) + { + pos = Adr2Pos(iniAdr); + //Check trivial initialization + if (iniProcSize > 8) recU->trivialIni = false; + SetFlag(cfProcStart, pos); + //SetFlag(cfProcEnd, pos + iniProcSize - 1); + recN = GetInfoRec(iniAdr); + if (!recN) recN = new InfoRec(pos, ikProc); + recN->procInfo->procSize = iniProcSize; + } + if (finAdr) + { + pos = Adr2Pos(finAdr); + //Check trivial finalization + if (finProcSize > 46) recU->trivialFin = false; + SetFlag(cfProcStart, pos); + //SetFlag(cfProcEnd, pos + finProcSize - 1); + recN = GetInfoRec(finAdr); + if (!recN) recN = new InfoRec(pos, ikProc); + recN->procInfo->procSize = finProcSize; + //import? + if (IsFlagSet(cfImport, pos)) + { + b = strchr(recN->GetName().c_str(), '@'); + if (b) + { + e = strchr(b + 1, '@'); + if (e) SetUnitName(recU, String(b + 1, e - b - 1)); + } + } + } + Units->Add((void*)recU); + } + + Units->Sort(&SortUnitsByAdr); + + start = CodeBase; + unitsNum = Units->Count; + for (i = 0; i < unitsNum; i++) + { + recU = (PUnitRec)Units->Items[i]; + recU->fromAdr = start; + if (recU->toAdr) start = recU->toAdr; + //Is unit trivial? + if (recU->trivialIni && recU->trivialFin) + { + int isize = (recU->iniSize + 3) & 0xFFFFFFFC; + int fsize = (recU->finSize + 3) & 0xFFFFFFFC; + if (isize + fsize == recU->toAdr - recU->fromAdr) recU->trivial = true; + } + //Last Unit has program name and toAdr = initTable + if (i == unitsNum - 1) + { + recU->toAdr = initTable; + SetUnitName(recU, dprName); + } + } + + return unitsNum; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::GetBCBUnits(String dprName) +{ + int n, pos, curPos, instrLen, iniNum, finNum, unitsNum, no; + DWORD dd, adr, curAdr, modTable, iniTable, iniTableEnd, finTable, finTableEnd, fromAdr, toAdr; + PUnitRec recU; + PInfoRec recN; + DISINFO disInfo; + + //EP: jmp @1 + curAdr = EP; curPos = Adr2Pos(curAdr); + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &disInfo, 0); + dd = *((DWORD*)disInfo.Mnem); + if (dd == 'pmj') + { + curAdr = disInfo.Immediate; curPos = Adr2Pos(curAdr); + while (1) + { + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &disInfo, 0); + dd = *((DWORD*)disInfo.Mnem); + if (dd == 'pmj') break; + if (dd == 'hsup' && disInfo.OpType[0] == otIMM && disInfo.Immediate) + { + modTable = disInfo.Immediate; + if (IsValidImageAdr(modTable)) + { + pos = Adr2Pos(modTable); + iniTable = *((DWORD*)(Image + pos)); + iniTableEnd = *((DWORD*)(Image + pos + 4)); + finTable = *((DWORD*)(Image + pos + 8)); + finTableEnd = *((DWORD*)(Image + pos + 12)); + for (n = 16; n < 32; n += 4) + { + adr = *((DWORD*)(Image + pos + n)); + if (IsValidImageAdr(adr)) + { + pos = Adr2Pos(adr); + SetFlag(cfProcStart, pos); + recN = GetInfoRec(adr); + if (!recN) recN = new InfoRec(pos, ikProc); + recN->SetName("WinMain"); + break; + } + } + + iniNum = (iniTableEnd - iniTable) / 6; + SetFlags(cfData, Adr2Pos(iniTable), iniTableEnd - iniTable); + finNum = (finTableEnd - finTable) / 6; + SetFlags(cfData, Adr2Pos(finTable), finTableEnd - finTable); + + TStringList* list = new TStringList; + list->Sorted = false; + list->Duplicates = dupIgnore; + if (iniNum > finNum) + { + pos = Adr2Pos(iniTable); + for (n = 0; n < iniNum; n++) + { + adr = *((DWORD*)(Image + pos + 2)); + pos += 6; + list->Add(Val2Str8(adr)); + } + } + else + { + pos = Adr2Pos(finTable); + for (n = 0; n < finNum; n++) + { + adr = *((DWORD*)(Image + pos + 2)); + pos += 6; + list->Add(Val2Str8(adr)); + } + } + list->Sort(); + fromAdr = CodeBase; no = 1; + for (n = 0; n < list->Count; n++) + { + recU = new UnitRec; + recU->trivial = false; + recU->trivialIni = true; + recU->trivialFin = true; + recU->kb = false; + recU->names = new TStringList; + + recU->matchedPercent = 0.0; + recU->iniOrder = no; no++; + + toAdr = StrToInt(String("$") + list->Strings[n]); + recU->finadr = 0; + recU->finSize = 0; + recU->iniadr = toAdr; + recU->iniSize = 0; + + recU->fromAdr = fromAdr; + recU->toAdr = toAdr; + Units->Add((void*)recU); + + fromAdr = toAdr; + if (n == list->Count - 1) SetUnitName(recU, dprName); + } + delete list; + Units->Sort(&SortUnitsByAdr); + return Units->Count; + } + } + curAdr += instrLen; curPos += instrLen; + } + } + return 0; +} +//--------------------------------------------------------------------------- +//-1 - not Code +//0 - possible Code +//1 - Code +int __fastcall TFMain_11011981::IsValidCode(DWORD fromAdr) +{ + BYTE op; + int firstPushReg, lastPopReg; + int firstPushPos, lastPopPos; + int row, num, instrLen, instrLen1, instrLen2; + int fromPos; + int curPos; + DWORD curAdr; + DWORD lastAdr = 0; + DWORD Adr, Adr1, Pos, lastMovAdr = 0; + PInfoRec recN; + DISINFO DisInfo; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return -1; + + if (fromAdr > EP) return -1; + //DISPLAY + if (!stricmp(Code + fromPos, "DISPLAY")) return -1; + + //recN = GetInfoRec(fromAdr); + int outRows = MAX_DISASSEMBLE; + if (IsFlagSet(cfImport, fromPos)) outRows = 1; + + firstPushReg = lastPopReg = -1; + firstPushPos = lastPopPos = -1; + curPos = fromPos; curAdr = fromAdr; + + for (row = 0; row < outRows; row++) + { + //Òàáëèöà exception + if (!IsValidImageAdr(curAdr)) return -1; + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + curPos += 4 + 8*num; curAdr += 4 + 8*num; + continue; + } + + BYTE b1 = Code[curPos]; + BYTE b2 = Code[curPos + 1]; + //00,00 - Data! + if (!b1 && !b2 && !lastAdr) return -1; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) return -1; + if (!instrLen)//???????? + { + curPos++; curAdr++; + continue; + } + if (!memcmp(DisInfo.Mnem, "arpl", 4) || + !memcmp(DisInfo.Mnem, "out", 3) || + (DisInfo.Mnem[0] == 'i' && DisInfo.Mnem[1] == 'n' && DisInfo.Mnem[2] != 'c')) + { + return -1; + } + op = Disasm.GetOp(DisInfo.Mnem); + + if (op == OP_JMP) + { + if (curAdr == fromAdr) break; + if (DisInfo.OpType[0] == otMEM) + { + if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) break; + } + if (DisInfo.OpType[0] == otIMM) + { + Adr = DisInfo.Immediate; Pos = Adr2Pos(Adr); + if (Pos < 0 && (!lastAdr || curAdr == lastAdr)) break; + if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) break; + if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) break; + curAdr = Adr; curPos = Pos; + continue; + } + } + + //Mark push or pop + if (op == OP_PUSH) + { + //Åñëè ïåðâàÿ èíñòðóêöèÿ íå push reg + if (!row && DisInfo.OpType[0] != otREG) return -1; + if (DisInfo.OpType[0] == otREG && firstPushReg == -1) + { + firstPushReg = DisInfo.OpRegIdx[0]; + firstPushPos = curPos; + } + } + else if (op == OP_POP) + { + if (DisInfo.OpType[0] == otREG) + { + lastPopReg = DisInfo.OpRegIdx[0]; + lastPopPos = curPos; + } + } + + //Îòáðàêîâêà ïî ïåðâîé èíñòðóêöèè + if (!row) + { + //Èíñòðóêöèÿ ïåðåõîäà èëè ret c àðãóìåíòàìè + if (DisInfo.Ret && DisInfo.OpNum >= 1) return -1; + if (DisInfo.Branch) return -1; + if (!memcmp(DisInfo.Mnem, "bound", 5) || + !memcmp(DisInfo.Mnem, "retf", 4) || + !memcmp(DisInfo.Mnem, "pop", 3) || + !memcmp(DisInfo.Mnem, "aaa", 3) || + !memcmp(DisInfo.Mnem, "adc", 3) || + !memcmp(DisInfo.Mnem, "sbb", 3) || + !memcmp(DisInfo.Mnem, "rcl", 3) || + !memcmp(DisInfo.Mnem, "rcr", 3) || + !memcmp(DisInfo.Mnem, "clc", 3) || + !memcmp(DisInfo.Mnem, "stc", 3)) + return -1; + } + //Åñëè â ïîçèöèè âñòðåòèëñÿ óæå îïðåäåëåííûé ðàíåå êîä, âûõîäèì + for (int k = 0; k < instrLen; k++) + { + if (IsFlagSet(cfProcStart, curPos + k) || IsFlagSet(cfCode, curPos + k)) + return -1; + } + + if (curAdr >= lastAdr) lastAdr = 0; + //Êîíåö ïðîöåäóðû + if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) + { + //Standard frame + if (Code[fromPos] == 0x55 && Code[fromPos + 1] == 0x8B && Code[fromPos + 2] == 0xEC) + break; + if (firstPushReg == lastPopReg && firstPushPos == fromPos && lastPopPos == curPos - 1) + break; + return 0; + } + + if (op == OP_MOV) lastMovAdr = DisInfo.Offset; + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + if (!IsValidCodeAdr(DisInfo.Offset)) break; + /* + //Ïåðâàÿ èíñòðóêöèÿ + if (curAdr == fromAdr) break; + */ + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Àäðåñ òàáëèöû - ïîñëåäíèå 4 áàéòà èíñòðóêöèè + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Àíàëèçèðóåì ïðîìåæóòîê íà ïðåäìåò òàáëèöû cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //Åñëè åñòü cTblAdr, ïðîïóñêàåì ýòó òàáëèöó + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + Pos += CNum; Adr += CNum; + } + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } + + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Äèçàññåìáëèðóåì jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + //if (!instrLen1) return -1; + + recN = GetInfoRec(DisInfo.Immediate); + if (recN) + { + if (recN->SameName("@HandleFinally")) + { + //jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + /* + //@2 + Adr1 = DisInfo.Immediate - 4; + Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); + if (Adr > lastAdr) lastAdr = Adr; + */ + } + else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //Ôëàæîê cfETable, ÷òîáû ïðàâèëüíî âûâåñòè äàííûå + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Pos += 4; + //dd offset ExceptionProc + Pos += 4; + } + } + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + if (b1 == 0xEB || //short relative abs jmp or cond jmp + (b1 >= 0x70 && b1 <= 0x7F) || + (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) + { + Adr = DisInfo.Immediate; + if (!IsValidImageAdr(Adr)) return -1; + if (IsValidCodeAdr(Adr)) + { + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + if (b1 == 0xE9) //relative abs jmp or cond jmp + { + Adr = DisInfo.Immediate; + if (!IsValidImageAdr(Adr)) return -1; + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (!recN && Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + curPos += instrLen; curAdr += instrLen; + } + return 1; +} +//--------------------------------------------------------------------------- +//Sort VmtList by height and vmtAdr +int __fastcall SortPairsCmpFunction(void *item1, void *item2) +{ + PVmtListRec rec1 = (PVmtListRec)item1; + PVmtListRec rec2 = (PVmtListRec)item2; + + if (rec1->height > rec2->height) return 1; + if (rec1->height < rec2->height) return -1; + if (rec1->vmtAdr > rec2->vmtAdr) return 1; + if (rec1->vmtAdr < rec2->vmtAdr) return -1; + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FillVmtList() +{ + VmtList->Clear(); + + for (int n = 0; n < TotalSize; n++) + { + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->kind == ikVMT && recN->HasName()) + { + PVmtListRec recV = new VmtListRec; + recV->height = GetClassHeight(Pos2Adr(n)); + recV->vmtAdr = Pos2Adr(n); + recV->vmtName = recN->GetName(); + VmtList->Add((void*)recV); + } + } + VmtList->Sort(SortPairsCmpFunction); +} +//--------------------------------------------------------------------------- +//Return virtual method offset of procedure with address procAdr +int __fastcall TFMain_11011981::GetMethodOfs(PInfoRec rec, DWORD procAdr) +{ + if (rec && rec->vmtInfo->methods) + { + for (int m = 0; m < rec->vmtInfo->methods->Count; m++) + { + PMethodRec recM = (PMethodRec)rec->vmtInfo->methods->Items[m]; + if (recM->kind == 'V' && recM->address == procAdr) return recM->id; + } + } + return -1; +} +//--------------------------------------------------------------------------- +//Return PMethodRec of method with given name +PMethodRec __fastcall TFMain_11011981::GetMethodInfo(PInfoRec rec, String name) +{ + if (rec && rec->vmtInfo->methods) + { + for (int m = 0; m < rec->vmtInfo->methods->Count; m++) + { + PMethodRec recM = (PMethodRec)rec->vmtInfo->methods->Items[m]; + if (SameText(recM->name, name)) return recM; + } + } + return 0; +} +//--------------------------------------------------------------------------- +//IntfTable ïðèñóòñòâóåò, åñëè êëàññ ïîðîæäåí îò èíòåðôåéñîâ +/* +Interfaces + Any class can implement any number of interfaces. The compiler stores a + table of interfaces as part of the class's RTTI. The VMT points to the table + of interfaces, which starts with a 4-byte count, followed by a list of + interface records. Each interface record contains the GUID, a pointer to the + interface's VMT, the offset to the interface's hidden field, and a pointer + to a property that implements the interface with the implements directive. + If the offset is zero, the interface property (called ImplGetter) must be + non-nil, and if the offset is not zero, ImplGetter must be nil. The interface + property can be a reference to a field, a virtual method, or a static method, + following the conventions of a property reader (which is described earlier + in this chapter, under Section 3.2.3"). When an object is constructed, Delphi + automatically checks all the interfaces, and for each interface with a + non-zero IOffset, the field at that offset is set to the interface's VTable + (a pointer to its VMT). Delphi defines the the types for the interface table, + unlike the other RTTI tables, in the System unit. These types are shown in + Example 3.9. + Example 3.9. Type Declarations for the Interface Table + + type + PInterfaceEntry = ^TInterfaceEntry; + TInterfaceEntry = record + IID: TGUID; + VTable: Pointer; + IOffset: Integer; + ImplGetter: Integer; + end; + + PInterfaceTable = ^TInterfaceTable; + TInterfaceTable = record + EntryCount: Integer; + // Declare the type with the largest possible size, + // but the true size of the array is EntryCount elements. + Entries: array[0..9999] of TInterfaceEntry; + //>=DXE2 + Intfs:array[0..EntryCount - 1] of PPTypeInfo; + end; + + TObject implements several methods for accessing the interface table. See for the details of the GetInterface, GetInterfaceEntry, and GetInterfaceTable methods. +*/ +void __fastcall TFMain_11011981::ScanIntfTable(DWORD adr) +{ + bool vmtProc; + WORD _dx, _bx, _si; + int n, pos, entryCount, cnt, vmtOfs, vpos, _pos, iOffset; + DWORD vmtAdr, intfAdr, vAdr, iAdr, _adr; + String className, name; + PInfoRec recN, recN1; + PMethodRec recM; + BYTE GUID[16]; + + if (!IsValidImageAdr(adr)) return; + + className = GetClsName(adr); + recN = GetInfoRec(adr); + vmtAdr = adr - cVmtSelfPtr; + pos = Adr2Pos(vmtAdr) + cVmtIntfTable; + intfAdr = *((DWORD*)(Code + pos)); + if (!intfAdr) return; + + pos = Adr2Pos(intfAdr); + entryCount = *((int*)(Code + pos)); pos += 4; + + for (n = 0; n < entryCount; n++) + { + memmove(GUID, Code + pos, 16); pos += 16; + //VTable + vAdr = *((DWORD*)(Code + pos)); pos += 4; + if (IsValidCodeAdr(vAdr)) + { + cnt = 0; + vpos = Adr2Pos(vAdr); + for (int v = 0;;v++) + { + if (IsFlagSet(cfVTable, vpos)) cnt++; + if (cnt == 2) break; + iAdr = *((DWORD*)(Code + vpos)); _adr = iAdr; + _pos = Adr2Pos(_adr); DISINFO disInfo; + vmtProc = false; vmtOfs = 0; + _dx = 0; _bx = 0; _si = 0; + while (1) + { + int instrlen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &disInfo, 0); + if ((disInfo.OpType[0] == otMEM || disInfo.OpType[1] == otMEM) && + disInfo.BaseReg != 20)//to exclude instruction "xchg reg, [esp]" + { + vmtOfs = disInfo.Offset; + } + if (disInfo.OpType[0] == otREG && disInfo.OpType[1] == otIMM) + { + if (disInfo.OpRegIdx[0] == 10)//dx + _dx = disInfo.Immediate; + else if (disInfo.OpRegIdx[0] == 11)//bx + _bx = disInfo.Immediate; + else if (disInfo.OpRegIdx[0] == 14)//si + _si = disInfo.Immediate; + } + if (disInfo.Call) + { + recN1 = GetInfoRec(disInfo.Immediate); + if (recN1) + { + if (recN1->SameName("@CallDynaInst") || + recN1->SameName("@CallDynaClass")) + { + if (DelphiVersion <= 5) + GetDynaInfo(adr, _bx, &iAdr); + else + GetDynaInfo(adr, _si, &iAdr); + break; + } + else if (recN1->SameName("@FindDynaInst") || + recN1->SameName("@FindDynaClass")) + { + GetDynaInfo(adr, _dx, &iAdr); + break; + } + } + } + if (disInfo.Branch && !disInfo.Conditional) + { + if (IsValidImageAdr(disInfo.Immediate)) + iAdr = disInfo.Immediate; + else + vmtProc = true; + break; + } + else if (disInfo.Ret) + { + vmtProc = true; + break; + } + _pos += instrlen; _adr += instrlen; + } + if (!vmtProc && IsValidImageAdr(iAdr)) + { + AnalyzeProcInitial(iAdr); + recN1 = GetInfoRec(iAdr); + if (recN1) + { + if (recN1->HasName()) + { + className = ExtractClassName(recN1->GetName()); + name = ExtractProcName(recN1->GetName()); + } + else + name = GetDefaultProcName(iAdr); + if (v >= 3) + { + if (!recN1->HasName()) recN1->SetName(className + "." + name); + } + } + } + vpos += 4; + } + } + //iOffset + iOffset = *((int*)(Code + pos)); pos += 4; + //ImplGetter + if (DelphiVersion > 3) pos += 4; + recN->vmtInfo->AddInterface(Val2Str8(vAdr) + " " + Val2Str4(iOffset) + " " + Guid2String(GUID)); + } +} +//--------------------------------------------------------------------------- +/* +Automated Methods + The automated section of a class declaration is now obsolete because it is + easier to create a COM automation server with Delphi's type library editor, + using interfaces. Nonetheless, the compiler currently supports automated + declarations for backward compatibility. A future version of the compiler + might drop support for automated declarations. + The OleAuto unit tells you the details of the automated method table: The + table starts with a 2-byte count, followed by a list of automation records. + Each record has a 4-byte dispid (dispatch identifier), a pointer to a short + string method name, 4-bytes of flags, a pointer to a list of parameters, + and a code pointer. The parameter list starts with a 1-byte return type, + followed by a 1-byte count of parameters, and ends with a list of 1-byte + parameter types. The parameter names are not stored. Example 3.8 shows the + declarations for the automated method table. + Example 3.8. The Layout of the Automated Method Table + + const + { Parameter type masks } + atTypeMask = $7F; + varStrArg = $48; + atByRef = $80; + MaxAutoEntries = 4095; + MaxAutoParams = 255; + + type + TVmtAutoType = Byte; + { Automation entry parameter list } + PAutoParamList = ^TAutoParamList; + TAutoParamList = packed record + ReturnType: TVmtAutoType; + Count: Byte; + Types: array[1..Count] of TVmtAutoType; + end; + { Automation table entry } + PAutoEntry = ^TAutoEntry; + TAutoEntry = packed record + DispID: LongInt; + Name: PShortString; + Flags: LongInt; { Lower byte contains flags } + Params: PAutoParamList; + Address: Pointer; + end; + + { Automation table layout } + PAutoTable = ^TAutoTable; + TAutoTable = packed record + Count: LongInt; + Entries: array[1..Count] of TAutoEntry; + end; +*/ +//Auto function prototype can be recovered from AutoTable!!! +void __fastcall TFMain_11011981::ScanAutoTable(DWORD Adr) +{ + if (!IsValidImageAdr(Adr)) return; + + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtAutoTable; + DWORD autoAdr = *((DWORD*)(Code + pos)); + if (!autoAdr) return; + + String className = GetClsName(Adr); + PInfoRec recN = GetInfoRec(Adr); + + pos = Adr2Pos(autoAdr); + int entryCount = *((int*)(Code + pos)); pos += 4; + + for (int i = 0; i < entryCount; i++) + { + int dispID = *((int*)(Code + pos)); pos += 4; + + DWORD nameAdr = *((DWORD*)(Code + pos)); pos += 4; + DWORD posn = Adr2Pos(nameAdr); + BYTE len = *(Code + posn); posn++; + String name = String((char*)(Code + posn), len); + String procname = className + "."; + + int flags = *((int*)(Code + pos)); pos += 4; + DWORD params = *((int*)(Code + pos)); pos += 4; + DWORD address = *((DWORD*)(Code + pos)); pos += 4; + + //afVirtual + if ((flags & 8) == 0) + { + //afPropGet + if (flags & 2) procname += "Get"; + //afPropSet + if (flags & 4) procname += "Set"; + } + else + { + //virtual table function + address = *((DWORD*)(Code + Adr2Pos(vmtAdr + address))); + } + + procname += name; + AnalyzeProcInitial(address); + PInfoRec recN1 = GetInfoRec(address); + if (!recN1) recN1 = new InfoRec(Adr2Pos(address), ikRefine); + if (!recN1->HasName()) recN1->SetName(procname); + //Method + if ((flags & 1) != 0) recN1->procInfo->flags |= PF_METHOD; + //params + int ppos = Adr2Pos(params); + BYTE typeCode = *(Code + ppos); ppos++; + BYTE paramsNum = *(Code + ppos); ppos++; + for (int m = 0; m < paramsNum; m++) + { + BYTE argType = *(Code + ppos); ppos++; + + } + recN->vmtInfo->AddMethod(false, 'A', dispID, address, procname); + } +} +//--------------------------------------------------------------------------- +/* +Initialization and Finalization + When Delphi constructs an object, it automatically initializes strings, + dynamic arrays, interfaces, and Variants. When the object is destroyed, + Delphi must decrement the reference counts for strings, interfaces, dynamic + arrays, and free Variants and wide strings. To keep track of this information, + Delphi uses initialization records as part of a class's RTTI. In fact, every + record and array that requires finalization has an associated initialization + record, but the compiler hides these records. The only ones you have access + to are those associated with an object's fields. + A VMT points to an initialization table. The table contains a list of + initialization records. Because arrays and records can be nested, each + initialization record contains a pointer to another initialization table, + which can contain initialization records, and so on. An initialization table + uses a TTypeKind field to keep track of whether it is initializing a string, + a record, an array, etc. + An initialization table begins with the type kind (1 byte), followed by the + type name as a short string, a 4-byte size of the data being initialized, a + 4-byte count for initialization records, and then an array of zero or more + initialization records. An initialization record is just a pointer to a + nested initialization table, followed by a 4-byte offset for the field that + must be initialized. Example 3.7 shows the logical layout of the initialization + table and record, but the declarations depict the logical layout without + being true Pascal code. + Example 3.7. The Layout of the Initialization Table and Record + + type + { Initialization/finalization record } + PInitTable = ^TInitTable; + TInitRecord = packed record + InitTable: ^PInitTable; + Offset: LongWord; // Offset of field in object + end; + { Initialization/finalization table } + TInitTable = packed record + {$MinEnumSize 1} // Ensure that TypeKind takes up 1 byte. + TypeKind: TTypeKind; + TypeName: packed ShortString; + DataSize: LongWord; + Count: LongWord; + // If TypeKind=ikArray, Count is the array size, but InitRecords + // has only one element; if the type kind is tkRecord, Count is the + // number of record members, and InitRecords[] has a + // record for each member. For all other types, Count=0. + InitRecords: array[1..Count] of TInitRecord; + end; +*/ +void __fastcall TFMain_11011981::ScanInitTable(DWORD Adr) +{ + if (!IsValidImageAdr(Adr)) return; + + PInfoRec recN = GetInfoRec(Adr); + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtInitTable; + DWORD initAdr = *((DWORD*)(Code + pos)); + if (!initAdr) return; + + pos = Adr2Pos(initAdr); + pos++; //skip 0xE + pos++; //unknown + pos += 4; //unknown + DWORD num = *((DWORD*)(Code + pos)); pos += 4; + + for (int i = 0; i < num; i++) + { + DWORD typeAdr = *((DWORD*)(Code + pos)); pos += 4; + DWORD post = Adr2Pos(typeAdr); + if (DelphiVersion != 2) post += 4; //skip SelfPtr + post++; //skip tkKind + BYTE len = *(Code + post); post++; + String typeName = String((char*)&Code[post], len); + if (typeName.Pos(":") > 0) + { + BYTE typeKind = GetTypeKind(typeAdr); + typeName = TransformShadowName(typeName, typeKind, typeAdr);//SHADOW + } + int fieldOfs = *((int*)(Code + pos)); pos += 4; + recN->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, "", typeName); + } +} +//--------------------------------------------------------------------------- +//For Version>=2010 +//Count: Word; // Published fields +//ClassTab: PVmtFieldClassTab +//Entry: array[1..Count] of TVmtFieldEntry +//ExCount: Word; +//ExEntry: array[1..ExCount] of TVmtFieldExEntry; +//================================================ +//TVmtFieldEntry +//FieldOffset: Longword; +//TypeIndex: Word; // index into ClassTab +//Name: ShortString; +//================================================ +//TFieldExEntry = packed record +//Flags: Byte; +//TypeRef: PPTypeInfo; +//Offset: Longword; +//Name: ShortString; +//AttrData: TAttrData +void __fastcall TFMain_11011981::ScanFieldTable(DWORD Adr) +{ + if (!IsValidImageAdr(Adr)) return; + + PInfoRec recN = GetInfoRec(Adr); + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtFieldTable; + DWORD fieldAdr = *((DWORD*)(Code + pos)); + if (!fieldAdr) return; + + pos = Adr2Pos(fieldAdr); + WORD count = *((WORD*)(Code + pos)); pos += 2; + DWORD typesTab = *((DWORD*)(Code + pos)); pos += 4; + + for (int i = 0; i < count; i++) + { + int fieldOfs = *((int*)(Code + pos)); pos += 4; + WORD idx = *((WORD*)(Code + pos)); pos += 2; + BYTE len = Code[pos]; pos++; + String name = String((char*)(Code + pos), len); pos += len; + + DWORD post = Adr2Pos(typesTab) + 2 + 4 * idx; + DWORD classAdr = *((DWORD*)(Code + post)); + if (IsFlagSet(cfImport, Adr2Pos(classAdr))) + { + PInfoRec recN1 = GetInfoRec(classAdr); + recN->vmtInfo->AddField(0, 0, FIELD_PUBLISHED, fieldOfs, -1, name, recN1->GetName()); + } + else + { + if (DelphiVersion == 2) classAdr += cVmtSelfPtr; + recN->vmtInfo->AddField(0, 0, FIELD_PUBLISHED, fieldOfs, -1, name, GetClsName(classAdr)); + } + } + if (DelphiVersion >= 2010) + { + WORD exCount = *((WORD*)(Code + pos)); pos += 2; + for (int i = 0; i < exCount; i++) + { + BYTE flags = Code[pos]; pos++; + DWORD typeRef = *((DWORD*)(Code + pos)); pos += 4; + int offset = *((int*)(Code + pos)); pos += 4; + BYTE len = Code[pos]; pos++; + String name = String((char*)(Code + pos), len); pos += len; + WORD dw = *((WORD*)(Code + pos)); pos += dw; + recN->vmtInfo->AddField(0, 0, FIELD_PUBLISHED, offset, -1, name, GetTypeName(typeRef)); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ScanMethodTable(DWORD adr, String className) +{ + BYTE len; + WORD skipNext; + DWORD codeAdr; + int spos, pos; + String name, methodName; + + if (!IsValidImageAdr(adr)) return; + + DWORD vmtAdr = adr - cVmtSelfPtr; + DWORD methodAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr) + cVmtMethodTable)); + if (!methodAdr) return; + + pos = Adr2Pos(methodAdr); + WORD count = *((WORD*)(Code + pos)); pos += 2; + + for (int n = 0; n < count; n++) + { + spos = pos; + skipNext = *((WORD*)(Code + pos)); pos += 2; + codeAdr = *((DWORD*)(Code + pos)); pos += 4; + len = Code[pos]; pos++; + name = String((char*)&Code[pos], len); pos += len; + + //as added why this code was removed? + methodName = className + "." + name; + DWORD pos1 = Adr2Pos(codeAdr); + PInfoRec recN1 = GetInfoRec(codeAdr); + if (!recN1) + { + recN1 = new InfoRec(pos1, ikRefine); + recN1->SetName(methodName); + } + //~ + + Infos[Adr2Pos(adr)]->vmtInfo->AddMethod(false, 'M', -1, codeAdr, methodName); + pos = spos + skipNext; + } + if (DelphiVersion >= 2010) + { + WORD exCount = *((WORD*)(Code + pos)); pos += 2; + for (int n = 0; n < exCount; n++) + { + //Entry + DWORD entry = *((DWORD*)(Code + pos)); pos += 4; + //Flags + pos += 2; + //VirtualIndex + pos += 2; + spos = pos; + //Entry + pos = Adr2Pos(entry); + skipNext = *((WORD*)(Code + pos)); pos += 2; + codeAdr = *((DWORD*)(Code + pos)); pos += 4; + len = Code[pos]; pos++; + name = String((char*)&Code[pos], len); pos += len; + Infos[Adr2Pos(adr)]->vmtInfo->AddMethod(false, 'M', -1, codeAdr, className + "." + name); + pos = spos; + } + } +} +//--------------------------------------------------------------------------- +typedef struct +{ + int id; + char *typname; + char *msgname; +} MsgInfo, *PMsgMInfo; + +MsgInfo WindowsMsgTab[] = +{ +{1, "WMCreate", "WM_CREATE"}, +{2, "WMDestroy", "WM_DESTROY"}, +{3, "WMMove", "WM_MOVE"}, +{5, "WMSize", "WM_SIZE"}, +{6, "WMActivate", "WM_ACTIVATE"}, +{7, "WMSetFocus", "WM_SETFOCUS"}, +{8, "WMKillFocus", "WM_KILLFOCUS"}, +{0xA, "WMEnable", "WM_ENABLE"}, +{0xB, "WMSetRedraw", "WM_SETREDRAW"}, +{0xC, "WMSetText", "WM_SETTEXT"}, +{0xD, "WMGetText", "WM_GETTEXT"}, +{0xE, "WMGetTextLength", "WM_GETTEXTLENGTH"}, +{0xF, "WMPaint", "WM_PAINT"}, +{0x10, "WMClose", "WM_CLOSE"}, +{0x11, "WMQueryEndSession", "WM_QUERYENDSESSION"}, +{0x12, "WMQuit", "WM_QUIT"}, +{0x13, "WMQueryOpen", "WM_QUERYOPEN"}, +{0x14, "WMEraseBkgnd", "WM_ERASEBKGND"}, +{0x15, "WMSysColorChange", "WM_SYSCOLORCHANGE"}, +{0x16, "WMEndSession", "WM_ENDSESSION"}, +{0x17, "WMSystemError", "WM_SYSTEMERROR"}, +{0x18, "WMShowWindow", "WM_SHOWWINDOW"}, +{0x19, "WMCtlColor", "WM_CTLCOLOR"}, +{0x1A, "WMSettingChange", "WM_SETTINGCHANGE"}, +{0x1B, "WMDevModeChange", "WM_DEVMODECHANGE"}, +{0x1C, "WMActivateApp", "WM_ACTIVATEAPP"}, +{0x1D, "WMFontChange", "WM_FONTCHANGE"}, +{0x1E, "WMTimeChange", "WM_TIMECHANGE"}, +{0x1F, "WMCancelMode", "WM_CANCELMODE"}, +{0x20, "WMSetCursor", "WM_SETCURSOR"}, +{0x21, "WMMouseActivate", "WM_MOUSEACTIVATE"}, +{0x22, "WMChildActivate", "WM_CHILDACTIVATE"}, +{0x23, "WMQueueSync", "WM_QUEUESYNC"}, +{0x24, "WMGetMinMaxInfo", "WM_GETMINMAXINFO"}, +{0x26, "WMPaintIcon", "WM_PAINTICON"}, +{0x27, "WMEraseBkgnd", "WM_ICONERASEBKGND"}, +{0x28, "WMNextDlgCtl", "WM_NEXTDLGCTL"}, +{0x2A, "WMSpoolerStatus", "WM_SPOOLERSTATUS"}, +{0x2B, "WMDrawItem", "WM_DRAWITEM"}, +{0x2C, "WMMeasureItem", "WM_MEASUREITEM"}, +{0x2D, "WMDeleteItem", "WM_DELETEITEM"}, +{0x2E, "WMVKeyToItem", "WM_VKEYTOITEM"}, +{0x2F, "WMCharToItem", "WM_CHARTOITEM"}, +{0x30, "WMSetFont", "WM_SETFONT"}, +{0x31, "WMGetFont", "WM_GETFONT"}, +{0x32, "WMSetHotKey", "WM_SETHOTKEY"}, +{0x33, "WMGetHotKey", "WM_GETHOTKEY"}, +{0x37, "WMQueryDragIcon", "WM_QUERYDRAGICON"}, +{0x39, "WMCompareItem", "WM_COMPAREITEM"}, +//{0x3D, "?", "WM_GETOBJECT"}, +{0x41, "WMCompacting", "WM_COMPACTING"}, +//{0x44, "?", "WM_COMMNOTIFY"}, +{0x46, "WMWindowPosChangingMsg", "WM_WINDOWPOSCHANGING"}, +{0x47, "WMWindowPosChangedMsg", "WM_WINDOWPOSCHANGED"}, +{0x48, "WMPower", "WM_POWER"}, +{0x4A, "WMCopyData", "WM_COPYDATA"}, +//{0x4B, "?", "WM_CANCELJOURNAL"}, +{0x4E, "WMNotify", "WM_NOTIFY"}, +//{0x50, "?", "WM_INPUTLANGCHANGEREQUEST"}, +//{0x51, "?", "WM_INPUTLANGCHANGE"}, +//{0x52, "?", "WM_TCARD"}, +{0x53, "WMHelp", "WM_HELP"}, +//{0x54, "?", "WM_USERCHANGED"}, +{0x55, "WMNotifyFormat", "WM_NOTIFYFORMAT"}, +{0x7B, "WMContextMenu", "WM_CONTEXTMENU"}, +{0x7C, "WMStyleChanging", "WM_STYLECHANGING"}, +{0x7D, "WMStyleChanged", "WM_STYLECHANGED"}, +{0x7E, "WMDisplayChange", "WM_DISPLAYCHANGE"}, +{0x7F, "WMGetIcon", "WM_GETICON"}, +{0x80, "WMSetIcon", "WM_SETICON"}, +{0x81, "WMNCCreate", "WM_NCCREATE"}, +{0x82, "WMNCDestroy", "WM_NCDESTROY"}, +{0x83, "WMNCCalcSize", "WM_NCCALCSIZE"}, +{0x84, "WMNCHitTest", "WM_NCHITTEST"}, +{0x85, "WMNCPaint", "WM_NCPAINT"}, +{0x86, "WMNCActivate", "WM_NCACTIVATE"}, +{0x87, "WMGetDlgCode", "WM_GETDLGCODE"}, +{0xA0, "WMNCMouseMove", "WM_NCMOUSEMOVE"}, +{0xA1, "WMNCLButtonDown", "WM_NCLBUTTONDOWN"}, +{0xA2, "WMNCLButtonUp", "WM_NCLBUTTONUP"}, +{0xA3, "WMNCLButtonDblClk", "WM_NCLBUTTONDBLCLK"}, +{0xA4, "WMNCRButtonDown", "WM_NCRBUTTONDOWN"}, +{0xA5, "WMNCRButtonUp", "WM_NCRBUTTONUP"}, +{0xA6, "WMNCRButtonDblClk", "WM_NCRBUTTONDBLCLK"}, +{0xA7, "WMNCMButtonDown", "WM_NCMBUTTONDOWN"}, +{0xA8, "WMNCMButtonUp", "WM_NCMBUTTONUP"}, +{0xA9, "WMNCMButtonDblClk", "WM_NCMBUTTONDBLCLK"}, +{0x100, "WMKeyDown", "WM_KEYDOWN"}, +{0x101, "WMKeyUp", "WM_KEYUP"}, +{0x102, "WMChar", "WM_CHAR"}, +{0x103, "WMDeadChar", "WM_DEADCHAR"}, +{0x104, "WMSysKeyDown", "WM_SYSKEYDOWN"}, +{0x105, "WMSysKeyUp", "WM_SYSKEYUP"}, +{0x106, "WMSysChar", "WM_SYSCHAR"}, +{0x107, "WMSysDeadChar", "WM_SYSDEADCHAR"}, +//{0x108, "?", "WM_KEYLAST"}, +//{0x10D, "?", "WM_IME_STARTCOMPOSITION"}, +//{0x10E, "?", "WM_IME_ENDCOMPOSITION"}, +//{0x10F, "?", "WM_IME_COMPOSITION"}, +{0x110, "WMInitDialog", "WM_INITDIALOG"}, +{0x111, "WMCommand", "WM_COMMAND"}, +{0x112, "WMSysCommand", "WM_SYSCOMMAND"}, +{0x113, "WMTimer", "WM_TIMER"}, +{0x114, "WMHScroll", "WM_HSCROLL"}, +{0x115, "WMVScroll", "WM_VSCROLL"}, +{0x116, "WMInitMenu", "WM_INITMENU"}, +{0x117, "WMInitMenuPopup", "WM_INITMENUPOPUP"}, +{0x11F, "WMMenuSelect", "WM_MENUSELECT"}, +{0x120, "WMMenuChar", "WM_MENUCHAR"}, +{0x121, "WMEnterIdle", "WM_ENTERIDLE"}, +//{0x122, "?", "WM_MENURBUTTONUP"}, +//{0x123, "?", "WM_MENUDRAG"}, +//{0x124, "?", "WM_MENUGETOBJECT"}, +//{0x125, "?", "WM_UNINITMENUPOPUP"}, +//{0x126, "?", "WM_MENUCOMMAND"}, +{0x127, "WMChangeUIState", "WM_CHANGEUISTATE"}, +{0x128, "WMUpdateUIState", "WM_UPDATEUISTATE"}, +{0x129, "WMQueryUIState", "WM_QUERYUISTATE"}, +{0x132, "WMCtlColorMsgBox", "WM_CTLCOLORMSGBOX"}, +{0x133, "WMCtlColorEdit", "WM_CTLCOLOREDIT"}, +{0x134, "WMCtlColorListBox", "WM_CTLCOLORLISTBOX"}, +{0x135, "WMCtlColorBtn", "WM_CTLCOLORBTN"}, +{0x136, "WMCtlColorDlg", "WM_CTLCOLORDLG"}, +{0x137, "WMCtlColorScrollBar", "WM_CTLCOLORSCROLLBAR"}, +{0x138, "WMCtlColorStatic", "WM_CTLCOLORSTATIC"}, +{0x200, "WMMouseMove", "WM_MOUSEMOVE"}, +{0x201, "WMLButtonDown", "WM_LBUTTONDOWN"}, +{0x202, "WMLButtonUp", "WM_LBUTTONUP"}, +{0x203, "WMLButtonDblClk", "WM_LBUTTONDBLCLK"}, +{0x204, "WMRButtonDown", "WM_RBUTTONDOWN"}, +{0x205, "WMRButtonUp", "WM_RBUTTONUP"}, +{0x206, "WMRButtonDblClk", "WM_RBUTTONDBLCLK"}, +{0x207, "WMMButtonDown", "WM_MBUTTONDOWN"}, +{0x208, "WMMButtonUp", "WM_MBUTTONUP"}, +{0x209, "WMMButtonDblClk", "WM_MBUTTONDBLCLK"}, +{0x20A, "WMMouseWheel", "WM_MOUSEWHEEL"}, +{0x210, "WMParentNotify", "WM_PARENTNOTIFY"}, +{0x211, "WMEnterMenuLoop", "WM_ENTERMENULOOP"}, +{0x212, "WMExitMenuLoop", "WM_EXITMENULOOP"}, +//{0x213, "?", "WM_NEXTMENU"}, +//{0x214, "?", "WM_SIZING"}, +//{0x215, "?", "WM_CAPTURECHANGED"}, +//{0x216, "?", "WM_MOVING"}, +//{0x218, "?", "WM_POWERBROADCAST"}, +//{0x219, "?", "WM_DEVICECHANGE"}, +{0x220, "WMMDICreate", "WM_MDICREATE"}, +{0x221, "WMMDIDestroy", "WM_MDIDESTROY"}, +{0x222, "WMMDIActivate", "WM_MDIACTIVATE"}, +{0x223, "WMMDIRestore", "WM_MDIRESTORE"}, +{0x224, "WMMDINext", "WM_MDINEXT"}, +{0x225, "WMMDIMaximize", "WM_MDIMAXIMIZE"}, +{0x226, "WMMDITile", "WM_MDITILE"}, +{0x227, "WMMDICascade", "WM_MDICASCADE"}, +{0x228, "WMMDIIconArrange", "WM_MDIICONARRANGE"}, +{0x229, "WMMDIGetActive", "WM_MDIGETACTIVE"}, +{0x230, "WMMDISetMenu", "WM_MDISETMENU"}, +//{0x231, "?", "WM_ENTERSIZEMOVE"}, +//{0x232, "?", "WM_EXITSIZEMOVE"}, +{0x233, "WMDropFiles", "WM_DROPFILES"}, +{0x234, "WMMDIRefreshMenu", "WM_MDIREFRESHMENU"}, +//{0x281, "?", "WM_IME_SETCONTEXT"}, +//{0x282, "?", "WM_IME_NOTIFY"}, +//{0x283, "?", "WM_IME_CONTROL"}, +//{0x284, "?", "WM_IME_COMPOSITIONFULL"}, +//{0x285, "?", "WM_IME_SELECT"}, +//{0x286, "?", "WM_IME_CHAR"}, +//{0x288, "?", "WM_IME_REQUEST"}, +//{0x290, "?", "WM_IME_KEYDOWN"}, +//{0x291, "?", "WM_IME_KEYUP"}, +//{0x2A1, "?", "WM_MOUSEHOVER"}, +//{0x2A3, "?", "WM_MOUSELEAVE"}, +{0x300, "WMCut", "WM_CUT"}, +{0x301, "WMCopy", "WM_COPY"}, +{0x302, "WMPaste", "WM_PASTE"}, +{0x303, "WMClear", "WM_CLEAR"}, +{0x304, "WMUndo", "WM_UNDO"}, +{0x305, "WMRenderFormat", "WM_RENDERFORMAT"}, +{0x306, "WMRenderAllFormats", "WM_RENDERALLFORMATS"}, +{0x307, "WMDestroyClipboard", "WM_DESTROYCLIPBOARD"}, +{0x308, "WMDrawClipboard", "WM_DRAWCLIPBOARD"}, +{0x309, "WMPaintClipboard", "WM_PAINTCLIPBOARD"}, +{0x30A, "WMVScrollClipboard", "WM_VSCROLLCLIPBOARD"}, +{0x30B, "WMSizeClipboard", "WM_SIZECLIPBOARD"}, +{0x30C, "WMAskCBFormatName", "WM_ASKCBFORMATNAME"}, +{0x30D, "WMChangeCBChain", "WM_CHANGECBCHAIN"}, +{0x30E, "WMHScrollClipboard", "WM_HSCROLLCLIPBOARD"}, +{0x30F, "WMQueryNewPalette", "WM_QUERYNEWPALETTE"}, +{0x310, "WMPaletteIsChanging", "WM_PALETTEISCHANGING"}, +{0x311, "WMPaletteChanged", "WM_PALETTECHANGED"}, +{0x312, "WMHotKey", "WM_HOTKEY"}, +//{0x317, "?", "WM_PRINT"}, +//{0x318, "?", "WM_PRINTCLIENT"}, +//{0x358, "?", "WM_HANDHELDFIRST"}, +//{0x35F, "?", "WM_HANDHELDLAST"}, +//{0x380, "?", "WM_PENWINFIRST"}, +//{0x38F, "?", "WM_PENWINLAST"}, +//{0x390, "?", "WM_COALESCE_FIRST"}, +//{0x39F, "?", "WM_COALESCE_LAST"}, +{0x3E0, "WMDDE_Initiate", "WM_DDE_INITIATE"}, +{0x3E1, "WMDDE_Terminate", "WM_DDE_TERMINATE"}, +{0x3E2, "WMDDE_Advise", "WM_DDE_ADVISE"}, +{0x3E3, "WMDDE_UnAdvise", "WM_DDE_UNADVISE"}, +{0x3E4, "WMDDE_Ack", "WM_DDE_ACK"}, +{0x3E5, "WMDDE_Data", "WM_DDE_DATA"}, +{0x3E6, "WMDDE_Request", "WM_DDE_REQUEST"}, +{0x3E7, "WMDDE_Poke", "WM_DDE_POKE"}, +{0x3E8, "WMDDE_Execute", "WM_DDE_EXECUTE"}, +{0, ""} +}; + +MsgInfo VCLControlsMsgTab[] = +{ +{0xB000, "CMActivate", "CM_ACTIVATE"}, +{0xB001, "CMDeactivate", "CM_DEACTIVATE"}, +{0xB002, "CMGotFocus", "CM_GOTFOCUS"}, +{0xB003, "CMLostFocus", "CM_LOSTFOCUS"}, +{0xB004, "CMCancelMode", "CM_CANCELMODE"}, +{0xB005, "CMDialogKey", "CM_DIALOGKEY"}, +{0xB006, "CMDialogChar", "CM_DIALOGCHAR"}, +{0xB007, "CMFocusChenged", "CM_FOCUSCHANGED"}, +{0xB008, "CMParentFontChanged", "CM_PARENTFONTCHANGED"}, +{0xB009, "CMParentColorChanged", "CM_PARENTCOLORCHANGED"}, +{0xB00A, "CMHitTest", "CM_HITTEST"}, +{0xB00B, "CMVisibleChanged", "CM_VISIBLECHANGED"}, +{0xB00C, "CMEnabledChanged", "CM_ENABLEDCHANGED"}, +{0xB00D, "CMColorChanged", "CM_COLORCHANGED"}, +{0xB00E, "CMFontChanged", "CM_FONTCHANGED"}, +{0xB00F, "CMCursorChanged", "CM_CURSORCHANGED"}, +{0xB010, "CMCtl3DChanged", "CM_CTL3DCHANGED"}, +{0xB011, "CMParentCtl3DChanged", "CM_PARENTCTL3DCHANGED"}, +{0xB012, "CMTextChanged", "CM_TEXTCHANGED"}, +{0xB013, "CMMouseEnter", "CM_MOUSEENTER"}, +{0xB014, "CMMouseLeave", "CM_MOUSELEAVE"}, +{0xB015, "CMMenuChanged", "CM_MENUCHANGED"}, +{0xB016, "CMAppKeyDown", "CM_APPKEYDOWN"}, +{0xB017, "CMAppSysCommand", "CM_APPSYSCOMMAND"}, +{0xB018, "CMButtonPressed", "CM_BUTTONPRESSED"}, +{0xB019, "CMShowingChanged", "CM_SHOWINGCHANGED"}, +{0xB01A, "CMEnter", "CM_ENTER"}, +{0xB01B, "CMExit", "CM_EXIT"}, +{0xB01C, "CMDesignHitTest", "CM_DESIGNHITTEST"}, +{0xB01D, "CMIconChanged", "CM_ICONCHANGED"}, +{0xB01E, "CMWantSpecialKey", "CM_WANTSPECIALKEY"}, +{0xB01F, "CMInvokeHelp", "CM_INVOKEHELP"}, +{0xB020, "CMWondowHook", "CM_WINDOWHOOK"}, +{0xB021, "CMRelease", "CM_RELEASE"}, +{0xB022, "CMShowHintChanged", "CM_SHOWHINTCHANGED"}, +{0xB023, "CMParentShowHintChanged", "CM_PARENTSHOWHINTCHANGED"}, +{0xB024, "CMSysColorChange", "CM_SYSCOLORCHANGE"}, +{0xB025, "CMWinIniChange", "CM_WININICHANGE"}, +{0xB026, "CMFontChange", "CM_FONTCHANGE"}, +{0xB027, "CMTimeChange", "CM_TIMECHANGE"}, +{0xB028, "CMTabStopChanged", "CM_TABSTOPCHANGED"}, +{0xB029, "CMUIActivate", "CM_UIACTIVATE"}, +{0xB02A, "CMUIDeactivate", "CM_UIDEACTIVATE"}, +{0xB02B, "CMDocWindowActivate", "CM_DOCWINDOWACTIVATE"}, +{0xB02C, "CMControlLIstChange", "CM_CONTROLLISTCHANGE"}, +{0xB02D, "CMGetDataLink", "CM_GETDATALINK"}, +{0xB02E, "CMChildKey", "CM_CHILDKEY"}, +{0xB02F, "CMDrag", "CM_DRAG"}, +{0xB030, "CMHintShow", "CM_HINTSHOW"}, +{0xB031, "CMDialogHanlde", "CM_DIALOGHANDLE"}, +{0xB032, "CMIsToolControl", "CM_ISTOOLCONTROL"}, +{0xB033, "CMRecreateWnd", "CM_RECREATEWND"}, +{0xB034, "CMInvalidate", "CM_INVALIDATE"}, +{0xB035, "CMSysFontChanged", "CM_SYSFONTCHANGED"}, +{0xB036, "CMControlChange", "CM_CONTROLCHANGE"}, +{0xB037, "CMChanged", "CM_CHANGED"}, +{0xB038, "CMDockClient", "CM_DOCKCLIENT"}, +{0xB039, "CMUndockClient", "CM_UNDOCKCLIENT"}, +{0xB03A, "CMFloat", "CM_FLOAT"}, +{0xB03B, "CMBorderChanged", "CM_BORDERCHANGED"}, +{0xB03C, "CMBiDiModeChanged", "CM_BIDIMODECHANGED"}, +{0xB03D, "CMParentBiDiModeChanged", "CM_PARENTBIDIMODECHANGED"}, +{0xB03E, "CMAllChildrenFlipped", "CM_ALLCHILDRENFLIPPED"}, +{0xB03F, "CMActionUpdate", "CM_ACTIONUPDATE"}, +{0xB040, "CMActionExecute", "CM_ACTIONEXECUTE"}, +{0xB041, "CMHintShowPause", "CM_HINTSHOWPAUSE"}, +{0xB044, "CMDockNotification", "CM_DOCKNOTIFICATION"}, +{0xB043, "CMMouseWheel", "CM_MOUSEWHEEL"}, +{0xB044, "CMIsShortcut", "CM_ISSHORTCUT"}, +{0xB045, "CMRawX11Event", "CM_RAWX11EVENT"}, +{0, "", ""} +}; + +PMsgMInfo __fastcall GetMsgInfo(WORD msg) +{ + //WindowsMsgTab + if (msg < 0x400) + { + for (int m = 0;; m++) + { + if (!WindowsMsgTab[m].id) break; + if (WindowsMsgTab[m].id == msg) return &WindowsMsgTab[m]; + } + } + //VCLControlsMsgTab + if (msg >= 0xB000 && msg < 0xC000) + { + for (int m = 0;; m++) + { + if (!VCLControlsMsgTab[m].id) break; + if (VCLControlsMsgTab[m].id == msg) return &VCLControlsMsgTab[m]; + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ScanDynamicTable(DWORD adr) +{ + PInfoRec recN, recN1, recN2; + + if (!IsValidImageAdr(adr)) return; + + recN = GetInfoRec(adr); + + if (!recN) return; + + DWORD vmtAdr = adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtDynamicTable; + DWORD dynamicAdr = *((DWORD*)(Code + pos)); + if (!dynamicAdr) return; + + String className = GetClsName(adr); + + pos = Adr2Pos(dynamicAdr); + WORD num = *((WORD*)(Code + pos)); pos += 2; + DWORD post = pos + 2 * num; + //First fill wellknown names + for (int i = 0; i < num; i++) + { + WORD msg = *((WORD*)(Code + pos)); pos += 2; + DWORD procAdr = *((DWORD*)(Code + post)); post += 4; + MethodRec recM; + recM.abstract = false; + recM.kind = 'D'; + recM.id = (int)msg; + recM.address = procAdr; + recM.name = ""; + + recN1 = GetInfoRec(procAdr); + if (recN1 && recN1->HasName()) + recM.name = recN1->GetName(); + else + { + PMsgMInfo _info = GetMsgInfo(msg); + if (_info) + { + String typname = _info->typname; + if (typname != "") + { + if (!recN1) recN1 = new InfoRec(Adr2Pos(procAdr), ikRefine); + recM.name = className + "." + typname; + recN1->SetName(recM.name); + } + } + if (recM.name == "") + { + DWORD parentAdr = GetParentAdr(adr); + while (parentAdr) + { + recN2 = GetInfoRec(parentAdr); + if (recN2) + { + DWORD vmtAdr1 = parentAdr - cVmtSelfPtr; + DWORD pos1 = Adr2Pos(vmtAdr1) + cVmtDynamicTable; + dynamicAdr = *((DWORD*)(Code + pos1)); + if (dynamicAdr) + { + pos1 = Adr2Pos(dynamicAdr); + WORD num1 = *((WORD*)(Code + pos1)); pos1 += 2; + DWORD post1 = pos1 + 2 * num1; + + for (int j = 0; j < num1; j++) + { + WORD msg1 = *((WORD*)(Code + pos1)); pos1 += 2; + DWORD procAdr1 = *((DWORD*)(Code + post1)); post1 += 4; + if (msg1 == msg) + { + recN2 = GetInfoRec(procAdr1); + if (recN2 && recN2->HasName()) + { + int dpos = recN2->GetName().Pos("."); + if (dpos) + recM.name = className + recN2->GetName().SubString(dpos, recN2->GetNameLength() - dpos + 1); + else + recM.name = recN2->GetName(); + } + break; + } + } + if (recM.name != "") break; + } + } + parentAdr = GetParentAdr(parentAdr); + } + } + + if (recM.name == "" || SameText(recM.name, "@AbstractError")) + recM.name = className + ".sub_" + Val2Str8(recM.address); + + recN1 = new InfoRec(Adr2Pos(procAdr), ikRefine); + recN1->SetName(recM.name); + } + recN->vmtInfo->AddMethod(recM.abstract, recM.kind, recM.id, recM.address, recM.name); + } +} +//--------------------------------------------------------------------------- +bool __fastcall IsOwnVirtualMethod(DWORD vmtAdr, DWORD procAdr) +{ + DWORD parentAdr = GetParentAdr(vmtAdr); + if (!parentAdr) return true; + DWORD stopAt = GetStopAt(parentAdr - cVmtSelfPtr); + if (vmtAdr == stopAt) return false; + + int pos = Adr2Pos(parentAdr) + cVmtParent + 4; + + for (int m = cVmtParent + 4;; m += 4, pos += 4) + { + if (Pos2Adr(pos) == stopAt) break; + + if (*((DWORD*)(Code + pos)) == procAdr) return false; + } + return true; +} +//--------------------------------------------------------------------------- +//Create recN->methods list +void __fastcall TFMain_11011981::ScanVirtualTable(DWORD adr) +{ + int m, pos, idx; + DWORD vmtAdr, stopAt; + String clsName; + PInfoRec recN, recN1; + MethodRec recM; + MProcInfo aInfo; + MProcInfo* pInfo = &aInfo; + + if (!IsValidImageAdr(adr)) return; + clsName = GetClsName(adr); + vmtAdr = adr - cVmtSelfPtr; + stopAt = GetStopAt(vmtAdr); + if (vmtAdr == stopAt) return; + + pos = Adr2Pos(vmtAdr) + cVmtParent + 4; + recN = GetInfoRec(vmtAdr + cVmtSelfPtr); + + for (m = cVmtParent + 4;; m += 4, pos += 4) + { + if (Pos2Adr(pos) == stopAt) break; + + recM.abstract = false; + recM.address = *((DWORD*)(Code + pos)); + + recN1 = GetInfoRec(recM.address); + if (recN1 && recN1->HasName()) + { + if (recN1->HasName()) + { + if (!recN1->SameName("@AbstractError")) + { + recM.name = recN1->GetName(); + } + else + { + recM.abstract = true; + recM.name = ""; + } + } + } + else + { + recM.name = ""; + if (m == cVmtFreeInstance) + recM.name = clsName + "." + "FreeInstance"; + else if (m == cVmtNewInstance) + recM.name = clsName + "." + "NewInstance"; + else if (m == cVmtDefaultHandler) + recM.name = clsName + "." + "DefaultHandler"; + if (DelphiVersion == 3 && m == cVmtSafeCallException) + recM.name = clsName + "." + "SafeCallException"; + if (DelphiVersion >= 4) + { + if (m == cVmtSafeCallException) + recM.name = clsName + "." + "SafeCallException"; + else if (m == cVmtAfterConstruction) + recM.name = clsName + "." + "AfterConstruction"; + else if (m == cVmtBeforeDestruction) + recM.name = clsName + "." + "BeforeDestruction"; + else if (m == cVmtDispatch) + recM.name = clsName + "." + "Dispatch"; + } + if (DelphiVersion >= 2009) + { + if (m == cVmtEquals) + recM.name = clsName + "." + "Equals"; + else if (m == cVmtGetHashCode) + recM.name = clsName + "." + "GetHashCode"; + else if (m == cVmtToString) + recM.name = clsName + "." + "ToString"; + } + if (recM.name != "" && KnowledgeBase.GetKBProcInfo(recM.name, pInfo, &idx)) + StrapProc(Adr2Pos(recM.address), idx, pInfo, true, pInfo->DumpSz); + } + recN->vmtInfo->AddMethod(recM.abstract, 'V', m, recM.address, recM.name); + } +} +//--------------------------------------------------------------------------- +//Âîçâðàùàåò "âûñîòó" êëàññà (÷èñëî ðîäèòåëüñêèõ êëàññîâ äî 0) +int __fastcall TFMain_11011981::GetClassHeight(DWORD adr) +{ + int level = 0; + while (1) + { + adr = GetParentAdr(adr); + if (!adr) break; + level++; + } + + return level; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::PropagateVMTNames(DWORD adr) +{ + String className = GetClsName(adr); + PInfoRec recN = GetInfoRec(adr); + + DWORD vmtAdr = adr - cVmtSelfPtr; + DWORD stopAt = GetStopAt(vmtAdr); + if (vmtAdr == stopAt) return; + + int pos = Adr2Pos(vmtAdr) + cVmtParent + 4; + for (int m = cVmtParent + 4;; m += 4, pos += 4) + { + if (Pos2Adr(pos) == stopAt) break; + + DWORD procAdr = *((DWORD*)(Code + pos)); + PInfoRec recN1 = GetInfoRec(procAdr); + if (!recN1) recN1 = new InfoRec(Adr2Pos(procAdr), ikRefine); + + if (!recN1->HasName()) + { + DWORD classAdr = adr; + while (classAdr) + { + PMethodRec recM = GetMethodInfo(classAdr, 'V', m); + if (recM) + { + String name = recM->name; + if (name != "") + { + int dotpos = name.Pos("."); + if (dotpos) + recN1->SetName(className + name.SubString(dotpos, name.Length())); + else + recN1->SetName(name); + + PInfoRec recN2 = GetInfoRec(recM->address); + recN1->kind = recN2->kind; + if (!recN1->procInfo->args && recN2->procInfo->args) + { + recN1->procInfo->flags |= recN2->procInfo->flags & 7; + //Get Arguments + for (int n = 0; n < recN2->procInfo->args->Count; n++) + { + PARGINFO argInfo2 = (PARGINFO)recN2->procInfo->args->Items[n]; + ARGINFO argInfo; + argInfo.Tag = argInfo2->Tag; + argInfo.Register = argInfo2->Register; + argInfo.Ndx = argInfo2->Ndx; + argInfo.Size = 4; + argInfo.Name = argInfo2->Name; + argInfo.TypeDef = TrimTypeName(argInfo2->TypeDef); + recN1->procInfo->AddArg(&argInfo); + } + } + recN->vmtInfo->AddMethod(false, 'V', m, procAdr, recN1->GetName()); + break; + } + } + classAdr = GetParentAdr(classAdr); + } + } + } +} +//--------------------------------------------------------------------------- +PMethodRec __fastcall TFMain_11011981::GetMethodInfo(DWORD adr, char kind, int methodOfs) +{ + if (!IsValidCodeAdr(adr)) return 0; + + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->id == methodOfs && recM->kind == kind) return recM; + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall ClearClassAdrMap() +{ + classAdrMap.clear(); +} +//--------------------------------------------------------------------------- +DWORD __fastcall FindClassAdrByName(const String& AName) +{ + TClassAdrMap::const_iterator it = classAdrMap.find(AName); + if (it != classAdrMap.end()) return it->second; + + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall AddClassAdr(DWORD Adr, const String& AName) +{ + classAdrMap[AName] = Adr; +} +//--------------------------------------------------------------------------- +//Âîçâðàùàåò îáùèé ðîäèòåëüñêèé òèï äëÿ òèïîâ Name1, Name2 +String __fastcall TFMain_11011981::GetCommonType(String Name1, String Name2) +{ + if (SameText(Name1, Name2)) return Name1; + + DWORD adr1 = GetClassAdr(Name1); + DWORD adr2 = GetClassAdr(Name2); + //Synonims + if (!adr1 || !adr2) + { + //dword and ClassName -> ClassName + if (SameText(Name1, "Dword") && IsValidImageAdr(GetClassAdr(Name2))) return Name2; + if (SameText(Name2, "Dword") && IsValidImageAdr(GetClassAdr(Name1))) return Name1; + if (DelphiVersion >= 2009) + { + //UString - UnicodeString + if ((SameText(Name1, "UString") && SameText(Name2, "UnicodeString")) || + (SameText(Name1, "UnicodeString") && SameText(Name2, "UString"))) return "UnicodeString"; + } + //String - AnsiString + if ((SameText(Name1, "String") && SameText(Name2, "AnsiString")) || + (SameText(Name1, "AnsiString") && SameText(Name2, "String"))) return "AnsiString"; + //Text - TTextRec + if ((SameText(Name1, "Text") && SameText(Name2, "TTextRec")) || + (SameText(Name1, "TTextRec") && SameText(Name2, "Text"))) return "TTextRec"; + return ""; + } + + int h1 = GetClassHeight(adr1); + int h2 = GetClassHeight(adr2); + + while (h1 != h2) + { + if (h1 > h2) + { + adr1 = GetParentAdr(adr1); + h1--; + } + else + { + adr2 = GetParentAdr(adr2); + h2--; + } + } + + while (adr1 != adr2) + { + adr1 = GetParentAdr(adr1); + adr2 = GetParentAdr(adr2); + } + + return GetClsName(adr1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormCreate(TObject *Sender) +{ + int n; + TMenuItem* mi; + LPCSTR buf[256]; + + if (!Disasm.Init()) + { + ShowMessage("Cannot initialize Disasm"); + Application->Terminate(); + } + + AppDir = ExtractFilePath(Application->ExeName); + if (AppDir[AppDir.Length()] != '\\') AppDir += "\\"; + Application->HelpFile = AppDir + "idr.chm"; + IniFileRead(); + + miDelphi2->Enabled = FileExists(AppDir + "kb2.bin"); + miDelphi3->Enabled = FileExists(AppDir + "kb3.bin"); + miDelphi4->Enabled = FileExists(AppDir + "kb4.bin"); + miDelphi5->Enabled = FileExists(AppDir + "kb5.bin"); + miDelphi6->Enabled = FileExists(AppDir + "kb6.bin"); + miDelphi7->Enabled = FileExists(AppDir + "kb7.bin"); + miDelphi2005->Enabled = FileExists(AppDir + "kb2005.bin"); + miDelphi2006->Enabled = FileExists(AppDir + "kb2006.bin"); + miDelphi2007->Enabled = FileExists(AppDir + "kb2007.bin"); + miDelphi2009->Enabled = FileExists(AppDir + "kb2009.bin"); + miDelphi2010->Enabled = FileExists(AppDir + "kb2010.bin"); + miDelphiXE1->Enabled = FileExists(AppDir + "kb2011.bin"); + miDelphiXE2->Enabled = FileExists(AppDir + "kb2012.bin"); + miDelphiXE3->Enabled = FileExists(AppDir + "kb2013.bin"); + miDelphiXE4->Enabled = FileExists(AppDir + "kb2014.bin"); + + SegmentList = new TList; + ExpFuncList = new TList; + ImpFuncList = new TList; + ImpModuleList = new TStringList; + VmtList = new TList; + ResInfo = new TResourceInfo; + Units = new TList; + OwnTypeList = new TList; + UnitsSearchList = new TStringList; + RTTIsSearchList = new TStringList; + UnitItemsSearchList = new TStringList; + VMTsSearchList = new TStringList; + FormsSearchList = new TStringList; + StringsSearchList = new TStringList; + NamesSearchList = new TStringList; + + Init(); + + lbUnits->Canvas->Font->Assign(lbUnits->Font); + lbRTTIs->Canvas->Font->Assign(lbRTTIs->Font); + lbForms->Canvas->Font->Assign(lbForms->Font); + lbCode->Canvas->Font->Assign(lbCode->Font); + lbUnitItems->Canvas->Font->Assign(lbUnitItems->Font); + lbSourceCode->Canvas->Font->Assign(lbSourceCode->Font); + + lbCXrefs->Canvas->Font->Assign(lbCXrefs->Font); + lbCXrefs->Width = lbCXrefs->Canvas->TextWidth("T")*14; + ShowCXrefs->Width = lbCXrefs->Width; + + lbSXrefs->Canvas->Font->Assign(lbSXrefs->Font); + lbSXrefs->Width = lbSXrefs->Canvas->TextWidth("T")*14; + ShowSXrefs->Width = lbSXrefs->Width; + + lbNXrefs->Canvas->Font->Assign(lbNXrefs->Font); + lbNXrefs->Width = lbNXrefs->Canvas->TextWidth("T")*14; + ShowNXrefs->Width = lbNXrefs->Width; +/* +//----Highlighting----------------------------------------------------------- + if (InitHighlight()) + { + lbSourceCode->Style = lbOwnerDrawFixed; + DelphiLbId = CreateHighlight(lbSourceCode->Handle, ID_DELPHI); + DelphiThemesCount = GetThemesCount(ID_DELPHI); + for (n = 0; n < DelphiThemesCount; n++) + { + mi = new TMenuItem(pmCode->Items); + GetThemeName(ID_DELPHI, (DWORD)n,(LPCSTR)buf, 256); + mi->Caption = String((char *)buf); + mi->Tag = n; + mi->OnClick = ChangeDelphiHighlightTheme; + miDelphiAppearance->Add(mi); + } + }; +//----Highlighting----------------------------------------------------------- +*/ + ScaleForm(this); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormDestroy(TObject *Sender) +{ + CloseProject(); + + delete SegmentList; + delete ExpFuncList; + delete ImpFuncList; + delete ImpModuleList; + delete VmtList; + delete ResInfo; + delete OwnTypeList; + delete UnitsSearchList; + delete RTTIsSearchList; + delete UnitItemsSearchList; + delete VMTsSearchList; + delete FormsSearchList; + delete StringsSearchList; + delete NamesSearchList; + + for (int n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + delete recU->names; + } + delete Units; +/* +//----Highlighting----------------------------------------------------------- + if (DeleteHighlight) + { + DeleteHighlight(DelphiLbId); + } + FreeHighlight(); +//----Highlighting----------------------------------------------------------- +*/ +} +//--------------------------------------------------------------------------- +String __fastcall GetFilenameFromLink(String LinkName) +{ + String result = ""; + IPersistFile* ppf; + IShellLink* pshl; + WIN32_FIND_DATA wfd; + + //Initialize COM-library + CoInitialize(NULL); + //Create COM-object and get pointer to interface IPersistFile + CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IPersistFile, (void**)(&ppf)); + //Load Shortcut + wchar_t* temp = new WCHAR[MAX_PATH]; + StringToWideChar(LinkName, temp, MAX_PATH); + ppf->Load(temp, STGM_READ); + delete[] temp; + + //Get pointer to IShellLink + ppf->QueryInterface(IID_IShellLink, (void**)(&pshl)); + //Find Object shortcut points to + pshl->Resolve(0, SLR_ANY_MATCH | SLR_NO_UI); + //Get Object name + char* targetName = new char[MAX_PATH]; + pshl->GetPath(targetName, MAX_PATH, &wfd, 0); + result = String(targetName); + delete[] targetName; + + pshl->Release(); + ppf->Release(); + + CoFreeUnusedLibraries(); + CoUninitialize(); + + return result; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormShow(TObject *Sender) +{ + if (ParamCount() > 0) + { + String FileName = ParamStr(1); + String fileExtension = ExtractFileExt(FileName); + //Shortcut + if (SameText(fileExtension, ".lnk")) + { + FileName = GetFilenameFromLink(FileName); + } + + if (IsExe(FileName)) + { + LoadDelphiFile1(FileName, DELHPI_VERSION_AUTO, true, true); + } + else if (IsIdp(FileName)) + { + OpenProject(FileName); + } + else + { + ShowMessage("File " + FileName + " is not executable or IDR project file"); + } + } + //Added by TerminatorX 31.12.2018 + //TerminatorX code BEGIN + //Cheking registry record *.exe/*.dll + bool exefile1, dllfile1; + TRegistry *reg = new TRegistry(KEY_EXECUTE); + reg->RootKey = HKEY_CLASSES_ROOT; + reg->OpenKey("\\exefile\\shell\\Open with IDR\\command\\", false); + exefile1 = reg->ValueExists(""); + reg->CloseKey(); + + reg->OpenKey("\\dllfile\\shell\\Open with IDR\\command\\", false); + dllfile1 = reg->ValueExists(""); + reg->CloseKey(); + delete reg; + + mniShellIntegration1->Checked = (exefile1 && dllfile1); + //TerminatorX code END +} +//--------------------------------------------------------------------------- +/* +void __fastcall TFMain_11011981::ScanImports() +{ + String name; + int *cnt = new int[KnowledgeBase.ModuleCount]; + //Ïîïðîáóåì ñêàíèðîâàòü èíòåðâàë àäðåñîâ áåçûìÿííûõ ìîäóëåé ïî èìåíàì èìïîðòèðóåìûõ ôóíêöèé + for (int m = 0; m < UnitsNum; m++) + { + PUnitRec recU = (PUnitRec)Units->Items[m]; + if (!recU->names->Count) + { + memset(cnt, 0, KnowledgeBase.ModuleCount*sizeof(int)); + + int fromPos = Adr2Pos(recU->fromAdr); + int toPos = Adr2Pos(recU->toAdr); + int totcnt = 0; + + for (int n = fromPos; n < toPos; n++) + { + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN && IsFlagSet(cfImport, n)) + { + name = ExtractProcName(recN->name); + KnowledgeBase.GetModuleIdsByProcName(name.c_str()); + for (int k = 0;;k++) + { + if (KnowledgeBase.Mods[k] == 0xFFFF) break; + cnt[KnowledgeBase.Mods[k]]++; + totcnt++; + } + } + } + + if (totcnt) + { + int num = 0; WORD id; + for (int k = 0; k < KnowledgeBase.ModuleCount; k++) + { + if (cnt[k] == totcnt) + { + id = k; + num++; + } + } + DWORD iniadr; PInfoRec recN; + //Åñëè âñå èìïîðòû íàøëèñü òîëüêî â îäíîì þíèòå, çíà÷èò ýòî îí è åñòü + if (num == 1) + { + name = KnowledgeBase.GetModuleName(id); + if (recU->names->IndexOf(name) == -1) + { + recU->kb = true; + SetUnitName(recU, name); + } + } + //Åñëè â íåñêîëüêèõ, ïîïðîáóåì ïîèñêàòü ïðîöåäóðû ïî cfProcStart (åñëè òàêîâûå èìåþòñÿ) + else + { + for (int k = 0; k < KnowledgeBase.ModuleCount; k++) + { + if (cnt[k] == totcnt) + { + id = k; + int FirstProcIdx, LastProcIdx; + if (!KnowledgeBase.GetProcIdxs(id, &FirstProcIdx, &LastProcIdx)) continue; + + for (int m = fromPos; m < toPos; m++) + { + if (IsFlagSet(cfProcStart, m) || !Flags[m]) + { + for (int Idx = FirstProcIdx; Idx <= LastProcIdx; Idx++) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + MProcInfo *pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS); + //Íàõîäèì ñîâïàäåíèå êîäà + if (KnowledgeBase.MatchCode(Code + m, pInfo) && StrapCheck(m, pInfo)) + { + name = KnowledgeBase.GetModuleName(id); + if (recU->names->IndexOf(name) == -1) + { + recU->kb = true; + SetUnitName(recU, name); + } + StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); + } + //as if (pInfo) delete pInfo; + } + } + } + } + } + } + } + } + } + } + delete[] cnt; +} +*/ +//--------------------------------------------------------------------------- +String __fastcall TFMain_11011981::MakeComment(PPICODE Picode) +{ + bool vmt; + DWORD vmtAdr; + String comment = ""; + + if (Picode->Op == OP_CALL || Picode->Op == OP_COMMENT) + { + comment = Picode->Name; + } + else + { + PFIELDINFO fInfo = GetField(Picode->Name, Picode->Ofs.Offset, &vmt, &vmtAdr, ""); + if (fInfo) + { + comment = Picode->Name + "."; + if (fInfo->Name == "") + comment += "?f" + Val2Str0(Picode->Ofs.Offset); + else + comment += fInfo->Name; + comment += ":"; + if (fInfo->Type == "") + comment += "?"; + else + comment += TrimTypeName(fInfo->Type); + + if (!vmt) delete fInfo; + } + else if (Picode->Name != "") + { + comment = Picode->Name + ".?f" + Val2Str0(Picode->Ofs.Offset) + ":?"; + } + } + return comment; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::RedrawCode() +{ + DWORD adr = CurProcAdr; + CurProcAdr = 0; + ShowCode(adr, lbCode->ItemIndex, lbCXrefs->ItemIndex, lbCode->TopIndex); +} +//--------------------------------------------------------------------------- +//MXXXXXXXX textF +//M:<,>,= +//XXXXXXXX - adr +//F - flags +int __fastcall TFMain_11011981::AddAsmLine(DWORD Adr, String text, BYTE Flags) +{ + String _line = " " + Val2Str8(Adr) + " " + text + " "; + if (Flags & 1) _line[1] = '>'; + if (Flags & 8) _line[10] = '>'; + + int _len = _line.Length(); + _line[_len] = Flags; + + lbCode->Items->Add(_line); + return lbCode->Canvas->TextWidth(_line); +} +//Argument SelectedIdx can be address (for selection) and index of list +void __fastcall TFMain_11011981::ShowCode(DWORD fromAdr, int SelectedIdx, int XrefIdx, int topIdx) +{ + BYTE op, flags; + int row = 0, wid, maxwid = 0, _pos, _idx, _ap; + TCanvas* canvas = lbCode->Canvas; + int num, instrLen, instrLen1, instrLen2, _procSize; + DWORD Adr, Adr1, Pos, lastMovAdr = 0; + int fromPos; + int curPos; + DWORD curAdr; + DWORD lastAdr = 0; + String line, line1; + PInfoRec recN; + DISINFO DisInfo, DisInfo1; + char disLine[100]; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return; + + bool selectByAdr = (IsValidImageAdr(SelectedIdx) == true); + /* + //If procedure is the same then move selection and not update Xrefs + if (fromAdr == CurProcAdr) + { + if (selectByAdr) + { + for (int i = 1; i < lbCode->Items->Count; i++) + { + line = lbCode->Items->Strings[i]; + sscanf(line.c_str() + 1, "%lX", &Adr); + if (Adr >= SelectedIdx) + { + if (Adr == SelectedIdx) + { + lbCode->ItemIndex = i; + break; + } + else + { + lbCode->ItemIndex = i - 1; + break; + } + } + } + } + else + lbCode->ItemIndex = SelectedIdx; + + pcWorkArea->ActivePage = tsCodeView; + return; + } + */ + if (!AnalyzeThread)//Clear all Items (used in highlighting) + { + //AnalyzeProc1(fromAdr, 0, 0, 0, false);//!!! + AnalyzeProc2(fromAdr, false, false); + } + + CurProcAdr = fromAdr; + CurProcSize = 0; + lbCode->Clear(); + lbCode->Items->BeginUpdate(); + + recN = GetInfoRec(fromAdr); + + int outRows = MAX_DISASSEMBLE; + if (IsFlagSet(cfImport, fromPos)) outRows = 2; + + line = " "; + if (fromAdr == EP) + { + line += "EntryPoint"; + } + else + { + String moduleName = ""; + String procName = ""; + + PUnitRec recU = GetUnit(fromAdr); + if (recU) + { + moduleName = GetUnitName(recU); + if (fromAdr == recU->iniadr) + procName = "Initialization"; + else if (fromAdr == recU->finadr) + procName = "Finalization"; + } + if (recN && procName == "") procName = recN->MakeMapName(fromAdr); + + if (moduleName != "") + line += moduleName + "." + procName; + else + line += procName; + } + lProcName->Caption = line; + lbCode->Items->Add(line); row++; + + _procSize = GetProcSize(fromAdr); + curPos = fromPos; curAdr = fromAdr; + + while (row < outRows) + { + //End of procedure + if (curAdr != fromAdr && _procSize && curAdr - fromAdr >= _procSize) break; + //Loc? + flags = ' '; + if (curAdr != CurProcAdr && IsFlagSet(cfLoc, curPos)) + flags |= 1; + if (IsFlagSet(cfFrame | cfSkip, curPos)) + flags |= 2; + if (IsFlagSet(cfLoop, curPos)) + flags |= 4; + + //If exception table, output it + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + wid = AddAsmLine(curAdr, "dd " + String(num), flags); row++; + if (wid > maxwid) maxwid = wid; + + curPos += 4; curAdr += 4; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Adr = *((DWORD*)(Code + curPos)); + line1 = "dd " + Val2Str8(Adr); + //Name of Exception + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN && recN->HasName()) line1 += ";" + recN->GetName(); + } + wid = AddAsmLine(curAdr, line1, flags); row++; + if (wid > maxwid) maxwid = wid; + + //dd offset ExceptionProc + curPos += 4; curAdr += 4; + Adr = *((DWORD*)(Code + curPos)); + wid = AddAsmLine(curAdr, "dd " + Val2Str8(Adr), flags); row++; + if (wid > maxwid) maxwid = wid; + + curPos += 4; curAdr += 4; + } + continue; + } + + BYTE b1 = Code[curPos]; + BYTE b2 = Code[curPos + 1]; + if (!b1 && !b2 && !lastAdr) break; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, disLine); + if (!instrLen) + { + wid = AddAsmLine(curAdr, "???", 0x22); row++; + if (wid > maxwid) maxwid = wid; + curPos++; curAdr++; + continue; + } + op = Disasm.GetOp(DisInfo.Mnem); + + //Check inside instruction Fixup or ThreadVar + bool NameInside = false; DWORD NameInsideAdr; + for (int k = 1; k < instrLen; k++) + { + if (Infos[curPos + k]) + { + NameInside = true; + NameInsideAdr= curAdr + k; + break; + } + } + + line = String(disLine); + + if (curAdr >= lastAdr) lastAdr = 0; + + //Proc end + if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) + { + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + break; + } + + if (op == OP_MOV) lastMovAdr = DisInfo.Offset; + + if (b1 == 0xEB || //short relative abs jmp or cond jmp + (b1 >= 0x70 && b1 <= 0x7F) || + (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + if (op == OP_JMP) + { + _ap = Adr2Pos(Adr); + recN = GetInfoRec(Adr); + if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) + { + line = "jmp " + recN->GetName(); + } + } + flags |= 8; + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (b1 == 0xE9) //relative abs jmp or cond jmp + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + _ap = Adr2Pos(Adr); + recN = GetInfoRec(Adr); + if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) + { + line = "jmp " + recN->GetName(); + } + flags |= 8; + if (!recN && Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (DisInfo.Call) //call sub_XXXXXXXX + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN && recN->HasName()) + { + line = "call " + recN->GetName(); + //Found @Halt0 - exit + if (recN->SameName("@Halt0") && fromAdr == EP && !lastAdr) + { + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + break; + } + } + } + recN = GetInfoRec(curAdr); + if (recN && recN->picode) line += ";" + MakeComment(recN->picode); + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + if (!IsValidCodeAdr(DisInfo.Offset)) break; + /* + //First instruction + if (curAdr == fromAdr) break; + */ + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Table address - last 4 bytes of instruction + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Analyze address range to find table cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //If exist cTblAdr, skip this table + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + for (int k = 0; k < CNum; k++) + { + BYTE db = Code[Pos]; + CTab[k] = db; + wid = AddAsmLine(Adr, "db " + String(db), 0x22); row++; + if (wid > maxwid) maxwid = wid; + Pos++; Adr++; + } + } + //Check transitions by negative register values (in Delphi 2009) + //bool neg = false; + //Adr1 = *((DWORD*)(Code + Pos - 4)); + //if (IsValidCodeAdr(Adr1) && IsFlagSet(cfLoc, Adr2Pos(Adr1))) neg = true; + + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + + //Add row to assembler listing + wid = AddAsmLine(Adr, "dd " + Val2Str8(Adr1), 0x22); row++; + if (wid > maxwid) maxwid = wid; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } +//---------------------------------- +//PosTry: xor reg, reg +// push ebp +// push offset @1 +// push fs:[reg] +// mov fs:[reg], esp +// ... +//@2: ... +//At @1 various variants: +//---------------------------------- +//@1: jmp @HandleFinally +// jmp @2 +//---------------------------------- +//@1: jmp @HandleAnyException +// call DoneExcept +//---------------------------------- +//@1: jmp HandleOnException +// dd num +//Äàëåå òàáëèöà èç num çàïèñåé âèäà +// dd offset ExceptionInfo +// dd offset ExceptionProc +//---------------------------------- + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN = GetInfoRec(DisInfo.Immediate); + if (recN) + { + if (recN->SameName("@HandleFinally")) + { + //jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + /* + //@2 + Adr1 = DisInfo.Immediate - 4; + Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); + if (IsValidCodeAdr(Adr) && Adr > lastAdr) lastAdr = Adr; + */ + } + else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //Set flag cfETable to correct output data + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Pos += 4; + //dd offset ExceptionProc + Pos += 4; + } + } + } + } + } + } + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + //Name inside instruction (Fixip, ThreadVar) + String namei = "", comment = "", name, pname, type, ptype; + if (NameInside) + { + recN = GetInfoRec(NameInsideAdr); + if (recN && recN->HasName()) + { + namei += recN->GetName(); + if (recN->type != "") namei += ":" + recN->type; + } + } + //comment + recN = GetInfoRec(curAdr); + if (recN && recN->picode) comment = MakeComment(recN->picode); + + DWORD targetAdr = 0; + if (IsValidImageAdr(DisInfo.Immediate)) + { + if (!IsValidImageAdr(DisInfo.Offset)) targetAdr = DisInfo.Immediate; + } + else if (IsValidImageAdr(DisInfo.Offset)) + targetAdr = DisInfo.Offset; + + if (targetAdr) + { + name = pname = type = ptype = ""; + _pos = Adr2Pos(targetAdr); + if (_pos >= 0) + { + recN = GetInfoRec(targetAdr); + if (recN) + { + if (recN->kind == ikResString) + { + name = recN->GetName() + ":PResStringRec"; + } + else + { + if (recN->HasName()) + { + name = recN->GetName(); + if (recN->type != "") type = recN->type; + } + else if (IsFlagSet(cfProcStart, _pos)) + name = GetDefaultProcName(targetAdr); + } + } + //For Delphi2 pointers to VMT are distinct + else if (DelphiVersion == 2) + { + recN = GetInfoRec(targetAdr + cVmtSelfPtr); + if (recN && recN->kind == ikVMT && recN->HasName()) + { + name = recN->GetName(); + } + } + Adr = *((DWORD*)(Code + _pos)); + if (IsValidImageAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN) + { + if (recN->HasName()) + { + pname = recN->GetName(); + ptype = recN->type; + } + else if (IsFlagSet(cfProcStart, _pos)) + pname = GetDefaultProcName(Adr); + } + } + } + else + { + _idx = BSSInfos->IndexOf(Val2Str8(targetAdr)); + if (_idx != -1) + { + recN = (PInfoRec)BSSInfos->Objects[_idx]; + name = recN->GetName(); + type = recN->type; + } + } + } + if (SameText(comment, name)) name = ""; + if (pname != "") + { + if (comment != "") comment += " "; + comment += "^" + pname; + if (ptype != "") comment += ":" + ptype; + } + else if (name != "") + { + if (comment != "") comment += " "; + comment += name; + if (type != "") comment += ":" + type; + } + + if (comment != "" || namei != "") + { + line += ";"; + if (comment != "") line += comment; + if (namei != "") line += "{" + namei + "}"; + } + if (line.Length() > MAXLEN) line = line.SubString(1, MAXLEN) + "..."; + wid = AddAsmLine(curAdr, line, flags); row++; + if (wid > maxwid) maxwid = wid; + curPos += instrLen; curAdr += instrLen; + } + + CurProcSize = (curAdr + instrLen) - CurProcAdr; + + if (selectByAdr) + { + for (int i = 1; i < lbCode->Items->Count; i++) + { + line = lbCode->Items->Strings[i]; + sscanf(line.c_str() + 1, "%lX", &Adr); + if (Adr >= SelectedIdx) + { + if (Adr == SelectedIdx) + { + lbCode->ItemIndex = i; + break; + } + else + { + lbCode->ItemIndex = i - 1; + break; + } + } + } + } + else + lbCode->ItemIndex = SelectedIdx; + + if (topIdx != -1) lbCode->TopIndex = topIdx; + lbCode->ItemHeight = lbCode->Canvas->TextHeight("T"); + lbCode->ScrollWidth = maxwid + 2; + lbCode->Items->EndUpdate(); + + ShowCodeXrefs(CurProcAdr, XrefIdx); + pcWorkArea->ActivePage = tsCodeView; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AnalyzeMethodTable(int Pass, DWORD Adr, const bool* Terminated) +{ + BYTE sLen, paramFlags, paramCount, cc; + WORD skipNext, dw, parOfs; + int procPos; + DWORD procAdr, paramType, resultType; + PInfoRec recN; + String paramName, methodName; + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD methodAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr) + cVmtMethodTable)); + + if (!methodAdr) return; + + String className = GetClsName(Adr); + int pos = Adr2Pos(methodAdr); + WORD count = *((WORD*)(Code + pos)); pos += 2; + + for (int n = 0; n < count && !*Terminated; n++) + { + skipNext = *((WORD*)(Code + pos)); + procAdr = *((DWORD*)(Code + pos + 2)); + procPos = Adr2Pos(procAdr); + sLen = Code[pos + 6]; + methodName = String((char*)(Code + pos + 7), sLen); + + AnalyzeProc(Pass, procAdr); + + if (Pass == 1) + { + recN = GetInfoRec(procAdr); + if (recN && recN->kind != ikConstructor && recN->kind != ikDestructor && recN->kind != ikClassRef) + { + recN->SetName(className + "." + methodName); + recN->kind = ikProc; + recN->AddXref('D', Adr, 0); + recN->procInfo->AddArg(0x21, 0, 4, "Self", className); + } + } + pos += skipNext; + } + if (DelphiVersion >= 2010) + { + WORD exCount = *((WORD*)(Code + pos)); pos += 2; + for (int n = 0; n < exCount && !*Terminated; n++) + { + DWORD methodEntry = *((DWORD*)(Code + pos)); pos += 4; + WORD flags = *((WORD*)(Code + pos)); pos += 2; + WORD vIndex = *((WORD*)(Code + pos)); pos += 2; + int spos = pos; + pos = Adr2Pos(methodEntry); + //Length + skipNext = *((WORD*)(Code + pos)); pos += 2; + procAdr = *((DWORD*)(Code + pos)); pos += 4; + procPos = Adr2Pos(procAdr); + sLen = Code[pos]; + methodName = String((char*)(Code + pos + 1), sLen); pos += sLen + 1; + + if (procAdr == Adr) continue; + + recN = GetInfoRec(procAdr); + //IMHO it means that methods are pure virtual calls and must be readed in child classes + if (recN && recN->kind == ikVMT) + { + pos = spos; + continue; + } + AnalyzeProc(Pass, procAdr); + recN = GetInfoRec(procAdr); + + if (Pass == 1) + { + if (recN && recN->procInfo && recN->kind != ikConstructor && recN->kind != ikDestructor)//recN->kind != ikClassRef + { + recN->SetName(className + "." + methodName); + recN->kind = ikProc; + recN->AddXref('D', Adr, 0); + recN->procInfo->AddArg(0x21, 0, 4, "Self", className); + } + } + if (pos - Adr2Pos(methodEntry) < skipNext) + { + //Version + pos++; + cc = Code[pos]; pos++; + resultType = *((DWORD*)(Code + pos)); pos += 4; + //ParOff + pos += 2; + if (Pass == 1) + { + if (recN && recN->procInfo && recN->kind != ikConstructor && recN->kind != ikDestructor)//recN->kind != ikClassRef) + { + if (resultType) + { + recN->kind = ikFunc; + recN->type = GetTypeName(resultType); + } + if (cc != 0xFF) recN->procInfo->flags |= cc; + } + } + paramCount = Code[pos]; pos++; + if (Pass == 1) + { + if (recN && recN->procInfo) + { + recN->procInfo->DeleteArgs(); + if (!paramCount) recN->procInfo->AddArg(0x21, 0, 4, "Self", className); + } + } + for (int m = 0; m < paramCount && !*Terminated; m++) + { + paramFlags = Code[pos]; pos++; + paramType = *((DWORD*)(Code + pos)); pos += 4; + //ParOff + parOfs = *((WORD*)(Code + pos)); pos += 2; + sLen = Code[pos]; + paramName = String((char*)(Code + pos + 1), sLen); pos += sLen + 1; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + if (paramFlags & 0x40) continue;//Result + if (Pass == 1) + { + if (recN && recN->procInfo)//recN->kind != ikClassRef) + { + Byte tag = 0x21; + if (paramFlags & 1) tag = 0x22; + recN->procInfo->AddArg(tag, parOfs, 4, paramName, GetTypeName(paramType)); + } + } + } + } + else + { + cc = 0xFF; + paramCount = 0; + } + pos = spos; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AnalyzeDynamicTable(int Pass, DWORD Adr, const bool* Terminated) +{ + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD DynamicAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr) + cVmtDynamicTable)); + if (!DynamicAdr) return; + + String clsName = GetClsName(Adr); + DWORD pos = Adr2Pos(DynamicAdr); + WORD Num = *((WORD*)(Code + pos)); pos += 2; + DWORD post = pos + 2 * Num; + + for (int i = 0; i < Num && !*Terminated; i++, post+=4) + { + //WORD Msg + pos += 2; + DWORD procAdr = *((DWORD*)(Code + post)); + int procPos = Adr2Pos(procAdr); + if (!procPos) continue;//Something wrong! + bool skip = (*(Code + procPos) == 0 && *(Code + procPos + 1) == 0); + if (!skip) AnalyzeProc(Pass, procAdr); + + if (Pass == 1 && !skip) + { + PInfoRec recN = GetInfoRec(procAdr); + if (recN) + { + recN->kind = ikProc; + recN->procInfo->flags |= PF_DYNAMIC; + recN->AddXref('D', Adr, 0); + recN->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AnalyzeVirtualTable(int Pass, DWORD Adr, const bool* Terminated) +{ + DWORD parentAdr = GetParentAdr(Adr); + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD stopAt = GetStopAt(vmtAdr); + if (vmtAdr == stopAt) return; + + int pos = Adr2Pos(vmtAdr) + cVmtParent + 4; + for (int n = cVmtParent + 4; !*Terminated; n += 4, pos += 4) + { + if (Pos2Adr(pos) == stopAt) break; + DWORD procAdr = *((DWORD*)(Code + pos)); + int procPos = Adr2Pos(procAdr); + bool skip = (*(Code + procPos) == 0 && *(Code + procPos + 1) == 0); + if (!skip) AnalyzeProc(Pass, procAdr); + PInfoRec recN = GetInfoRec(procAdr); + + if (recN) + { + if (Pass == 1 && !skip) + { + recN->procInfo->flags |= PF_VIRTUAL; + recN->AddXref('D', Adr, 0); + } + + DWORD pAdr = parentAdr; + while (pAdr&& !*Terminated) + { + PInfoRec recN1 = GetInfoRec(pAdr); + //Look at parent class methods + if (recN1 && recN1->vmtInfo && recN1->vmtInfo->methods) + { + for (int m = 0; m < recN1->vmtInfo->methods->Count; m++) + { + PMethodRec recM = (PMethodRec)recN1->vmtInfo->methods->Items[m]; + if (recM->abstract && recM->kind == 'V' && recM->id == n && recM->name == "") + { + String procName = recN->GetName(); + if (procName != "" && !SameText(procName, "@AbstractError")) + { + recM->name = GetClsName(pAdr) + "." + ExtractProcName(procName); + } + break; + } + } + } + pAdr = GetParentAdr(pAdr); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AnalyzeProc(int pass, DWORD procAdr) +{ + switch (pass) + { + case 0: + AnalyzeProcInitial(procAdr); + break; + case 1: + AnalyzeProc1(procAdr, 0, 0, 0, false); + break; + case 2: + AnalyzeProc2(procAdr, true, true); + break; + } +} +//--------------------------------------------------------------------------- +//Scan proc calls +DWORD __fastcall TFMain_11011981::AnalyzeProcInitial(DWORD fromAdr) +{ + BYTE op, b1, b2; + int num, instrLen, instrLen1, instrLen2, _procSize; + int fromPos; + int curPos; + DWORD curAdr; + DWORD lastAdr = 0; + DWORD Adr, Adr1, Pos, lastMovAdr = 0; + PInfoRec recN; + DISINFO DisInfo, DisInfo1; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return 0; + if (IsFlagSet(cfPass0, fromPos)) return 0; + if (IsFlagSet(cfEmbedded, fromPos)) return 0; + if (IsFlagSet(cfExport, fromPos)) return 0; + + //b1 = Code[fromPos]; + //b2 = Code[fromPos + 1]; + //if (!b1 && !b2) return 0; + + SetFlag(cfProcStart | cfPass0, fromPos); + + //Don't analyze imports + if (IsFlagSet(cfImport, fromPos)) return 0; + + _procSize = GetProcSize(fromAdr); + curPos = fromPos; curAdr = fromAdr; + + while (1) + { + if (curAdr >= CodeBase + TotalSize) break; + //For example, cfProcEnd can be set for interface procs + if (_procSize && curAdr - fromAdr >= _procSize) break; + //Skip exception table + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + curPos += 4 + 8*num; curAdr += 4 + 8*num; + continue; + } + + b1 = Code[curPos]; + b2 = Code[curPos + 1]; + if (!b1 && !b2 && !lastAdr) break; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); + //if (!instrLen) break; + if (!instrLen) + { + curPos++; curAdr++; + continue; + } + + op = Disasm.GetOp(DisInfo.Mnem); + //Code + SetFlags(cfCode, curPos, instrLen); + //Instruction begin + SetFlag(cfInstruction, curPos); + + if (curAdr >= lastAdr) lastAdr = 0; + + //End of procedure + if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) break; + + if (op == OP_MOV) lastMovAdr = DisInfo.Offset; + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + if (!IsValidCodeAdr(DisInfo.Offset)) break; + /* + //First instruction + if (curAdr == fromAdr) break; + */ + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Table address - last 4 bytes of instruction + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Scan gap to find table cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //If exists cTblAdr skip it + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + Pos += CNum; Adr += CNum; + } + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //Check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + int delta = Pos - NPos; + if (delta >= 0 && delta < MAX_DISASSEMBLE) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN = GetInfoRec(DisInfo.Immediate); + if (recN) + { + if (recN->SameName("@HandleFinally")) + { + //jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + /* + //@2 + Adr1 = DisInfo.Immediate - 4; + Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); + if (Adr > lastAdr) lastAdr = Adr; + */ + } + else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //Set flag cfETable to correctly output data + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Pos += 4; + //dd offset ExceptionProc + Pos += 4; + } + } + } + } + } + curPos += instrLen; curAdr += instrLen; + continue; + } + } + } + + if (DisInfo.Call) //call sub_XXXXXXXX + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + //If @Halt0 - end of procedure + if (recN && recN->SameName("@Halt0")) + { + if (fromAdr == EP && !lastAdr) break; + } + AnalyzeProcInitial(Adr); + } + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (op == OP_JMP) + { + if (curAdr == fromAdr) return 0; + if (DisInfo.OpType[0] == otMEM) + { + if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) return 0; + } + if (DisInfo.OpType[0] == otIMM) + { + Adr = DisInfo.Immediate; + if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) return 0; + if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) return 0; + if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) return Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (DisInfo.Conditional) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + curPos += instrLen; curAdr += instrLen; + continue; + } + curPos += instrLen; curAdr += instrLen; + } +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::CodeGetTargetAdr(String Line, DWORD* trgAdr) +{ + char *s, *p, c; + int n, wid, instrlen; + DWORD adr, targetAdr; + TPoint cursorPos; + TCanvas* canvas = lbCode->Canvas; + DISINFO DisInfo; + + *trgAdr = 0; + s = Line.c_str() + 1; + + //If db - no address + if (strstr(s, " db ")) return 0; + //If dd - address + p = strstr(s, " dd "); + if (p) sscanf(p + 4, "%lX", &targetAdr); + + if (!IsValidImageAdr(targetAdr)) + { + sscanf(s, "%lX", &adr); + instrlen = Disasm.Disassemble(Code + Adr2Pos(adr), (__int64)adr, &DisInfo, 0); + if (!instrlen) return 0; + + if (IsValidImageAdr(DisInfo.Immediate)) + { + if (!IsValidImageAdr(DisInfo.Offset)) + targetAdr = DisInfo.Immediate; + } + else if (IsValidImageAdr(DisInfo.Offset)) + targetAdr = DisInfo.Offset; + } + if (!IsValidImageAdr(targetAdr)) + { + GetCursorPos(&cursorPos); + cursorPos = lbCode->ScreenToClient(cursorPos); + for (n = 0, wid = 0; n < strlen(s); n++) + { + int cwid = canvas->TextWidth(s[n]); + if (wid >= cursorPos.x) + { + while (n >= 0) + { + c = s[n]; + if (c == ' ' || c == ',' || c == '[' || c == '+') + { + sscanf(s + n + 1, "%lX", &targetAdr); + break; + } + n--; + } + break; + } + wid += cwid; + } + } + if (IsValidImageAdr(targetAdr)) *trgAdr = targetAdr; + return DisInfo.OpSize; +} +//--------------------------------------------------------------------------- +//May be Plugin!!! +String __fastcall sub_004AFB28(BYTE* AStr) +{ + Integer _n, _num; + Byte _b, _b1, _b2, _m; + String _result; + + if (AStr[0] == 0x7B) + { + _m = 1; + _n = 2; + _b1 = AStr[1]; + _num = _b1 ^ 0xA1; + _result = ""; + if (_num > 0) + { + do + { + _b2 = AStr[_n]; + _b1 = (3 * _m + _b1) ^ _b2; + _b = _b1; + _b1 = _b2; + _m = _m + 1; + _n = _n + 1; + _num = _num - 1; + _b2 = AStr[_n]; + _b1 = (3 * _m + _b1) ^ _b2; + _b = _b | _b1; + if (_b) + { + _result += Char(_b); + } + _b1 = _b2; + _m = _m + 1; + _n = _n + 1; + _num = _num - 1; + } + while (_num > 0); + } + } + else + { + _result = "!"; + } + return _result; +} +//--------------------------------------------------------------------------- +void __fastcall sub_004AF80C(BYTE* AStr1, BYTE* AStr2) +{ + BYTE* _p; + BYTE _b, _n; + int _num; + + _n = *(AStr1 + 7); + _p = AStr1 + 2 + 8; + _num = AStr2 - _p; + if (_num > 0) + { + do + { + _b = *_p; + _b = ((0xFF - _b + 12) ^ 0xC2) - 3 * _n - 0x62; + *_p = _b; + _p++; + _n++; + _num--; + } + while (_num > 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbCodeDblClick(TObject *Sender) +{ + int pos, bytes, size; + DWORD adr, adr1, targetAdr; + PInfoRec recN; + PROCHISTORYREC rec; + String text; + + if (lbCode->ItemIndex <= 0) return; + + text = lbCode->Items->Strings[lbCode->ItemIndex]; + size = CodeGetTargetAdr(text, &targetAdr); + + if (IsValidImageAdr(targetAdr)) + { + pos = Adr2Pos(targetAdr); + if (pos == -2) return; + if (pos == -1) + { + ShowMessage("BSS"); + return; + } + if (IsFlagSet(cfImport, pos)) + { + ShowMessage("Import"); + return; + } + //RTTI + if (IsFlagSet(cfRTTI, pos)) + { + FTypeInfo_11011981->ShowRTTI(targetAdr); + return; + } + //if start of procedure, show it + if (IsFlagSet(cfProcStart, pos)) + { + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(Pos2Adr(pos), targetAdr, -1, -1); + CodeHistoryPush(&rec); + return; + } + + recN = GetInfoRec(targetAdr); + if (recN) + { + if (recN->kind == ikVMT && tsClassView->TabVisible) + { + ShowClassViewer(targetAdr); + return; + } + if (recN->kind == ikResString) + { + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->Caption = "ResString context"; + FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); + FStringInfo_11011981->ShowModal(); + return; + } + if (recN->HasName()) + { + WORD *uses = KnowledgeBase.GetTypeUses(recN->GetName().c_str()); + int idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, recN->GetName().c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + MTypeInfo tInfo; + if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS | INFO_DUMP, &tInfo)) + { + FTypeInfo_11011981->ShowKbInfo(&tInfo); + //as delete tInfo; + return; + } + } + } + } + //may be -> + adr = *((DWORD*)(Code + pos)); + if (IsValidImageAdr(adr)) + { + recN = GetInfoRec(adr); + if (recN) + { + if (recN->kind == ikResString) + { + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->Caption = "ResString context"; + FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); + FStringInfo_11011981->ShowModal(); + return; + } + } + } + + //if in current proc + if (CurProcAdr <= targetAdr && targetAdr < CurProcAdr + CurProcSize) + { + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(CurProcAdr, targetAdr, lbCXrefs->ItemIndex, -1); + CodeHistoryPush(&rec); + return; + } + //Else show explorer + FExplorer_11011981->tsCode->TabVisible = true; + FExplorer_11011981->ShowCode(targetAdr, 1024); + FExplorer_11011981->tsData->TabVisible = true; + FExplorer_11011981->ShowData(targetAdr, 1024); + FExplorer_11011981->tsString->TabVisible = true; + FExplorer_11011981->ShowString(targetAdr, 1024); + FExplorer_11011981->tsText->TabVisible = false; + FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsData; + FExplorer_11011981->WAlign = -4; + + FExplorer_11011981->btnDefCode->Enabled = true; + if (IsFlagSet(cfCode, pos)) FExplorer_11011981->btnDefCode->Enabled = false; + FExplorer_11011981->btnUndefCode->Enabled = false; + if (IsFlagSet(cfCode | cfData, pos)) FExplorer_11011981->btnUndefCode->Enabled = true; + + if (FExplorer_11011981->ShowModal() == mrOk) + { + if (FExplorer_11011981->DefineAs == DEFINE_AS_CODE) + { + //Delete any information at this address + recN = GetInfoRec(Pos2Adr(pos)); + if (recN) delete recN; + //Create new info about proc + recN = new InfoRec(pos, ikRefine); + + //AnalyzeProcInitial(targetAdr); + AnalyzeProc1(targetAdr, 0, 0, 0, false); + AnalyzeProc2(targetAdr, true, true); + AnalyzeArguments(targetAdr); + AnalyzeProc2(targetAdr, true, true); + + if (!ContainsUnexplored(GetUnit(targetAdr))) ShowUnits(true); + ShowUnitItems(GetUnit(targetAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(targetAdr, 0, -1, -1); + CodeHistoryPush(&rec); + ProjectModified = true; + } + } + } + //Try picode + else + { + sscanf(text.c_str() + 2, "%lX", &adr); + recN = GetInfoRec(adr); + if (recN && recN->picode && IsValidCodeAdr(recN->picode->Ofs.Address)) + { + pos = Adr2Pos(recN->picode->Ofs.Address); + if (IsFlagSet(cfProcStart, pos)) + { + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(Pos2Adr(pos), targetAdr, -1, -1); + CodeHistoryPush(&rec); + return; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::bEPClick(TObject *Sender) +{ + PROCHISTORYREC rec; + + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(EP, 0, -1, -1); + CodeHistoryPush(&rec); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::GoToAddress() +{ + int pos; + DWORD gotoAdr; + String sAdr; + PROCHISTORYREC rec; + + //if (lbCode->ItemIndex <= 0) return; + + sAdr = InputDialogExec("Enter Address", "Address:", ""); + if (sAdr != "") + { + sscanf(sAdr.c_str(), "%lX", &gotoAdr); + if (IsValidCodeAdr(gotoAdr)) + { + pos = Adr2Pos(gotoAdr); + //Åñëè èìïîðò - íè÷åãî íå îòîáðàæàåì + if (IsFlagSet(cfImport, pos)) return; + //Èùåì, êóäà ïîïàäàåò àäðåñ + while (pos >= 0) + { + //Íàøëè íà÷àëî ïðîöåäóðû + if (IsFlagSet(cfProcStart, pos)) + { + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(Pos2Adr(pos), gotoAdr, -1, -1); + CodeHistoryPush(&rec); + break; + } + //Íàøëè íà÷àëî òèïà + if (IsFlagSet(cfRTTI, pos)) + { + FTypeInfo_11011981->ShowRTTI(Pos2Adr(pos)); + break; + } + pos--; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miGoToClick(TObject *Sender) +{ + GoToAddress(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExploreAdrClick(TObject *Sender) +{ + int size; + DWORD viewAdr; + String text = "", sAdr; + PInfoRec recN; + + if (lbCode->ItemIndex <= 0) return; + + size = CodeGetTargetAdr(lbCode->Items->Strings[lbCode->ItemIndex], &viewAdr); + if (viewAdr) text = Val2Str8(viewAdr); + sAdr = InputDialogExec("Enter Address", "Address:", text); + if (sAdr != "") + { + sscanf(sAdr.c_str(), "%lX", &viewAdr); + if (IsValidImageAdr(viewAdr)) + { + int pos = Adr2Pos(viewAdr); + if (pos == -2) return; + if (pos == -1) + { + ShowMessage("BSS"); + return; + } + FExplorer_11011981->tsCode->TabVisible = true; + FExplorer_11011981->ShowCode(viewAdr, 1024); + FExplorer_11011981->tsData->TabVisible = true; + FExplorer_11011981->ShowData(viewAdr, 1024); + FExplorer_11011981->tsString->TabVisible = true; + FExplorer_11011981->ShowString(viewAdr, 1024); + FExplorer_11011981->tsText->TabVisible = false; + FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsCode; + FExplorer_11011981->WAlign = -4; + + FExplorer_11011981->btnDefCode->Enabled = true; + if (IsFlagSet(cfCode, pos)) FExplorer_11011981->btnDefCode->Enabled = false; + FExplorer_11011981->btnUndefCode->Enabled = false; + if (IsFlagSet(cfCode | cfData, pos)) FExplorer_11011981->btnUndefCode->Enabled = true; + + if (FExplorer_11011981->ShowModal() == mrOk) + { + switch (FExplorer_11011981->DefineAs) + { + case DEFINE_AS_CODE: + //Delete any information at this address + recN = GetInfoRec(viewAdr); + if (recN) delete recN; + //Create new info about proc + recN = new InfoRec(pos, ikRefine); + + //AnalyzeProcInitial(viewAdr); + AnalyzeProc1(viewAdr, 0, 0, 0, false); + AnalyzeProc2(viewAdr, true, true); + AnalyzeArguments(viewAdr); + AnalyzeProc2(viewAdr, true, true); + + if (!ContainsUnexplored(GetUnit(viewAdr))) ShowUnits(true); + ShowUnitItems(GetUnit(viewAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + ShowCode(viewAdr, 0, -1, -1); + break; + case DEFINE_AS_STRING: + break; + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::NamePosition() +{ + int pos, _idx, size; + DWORD adr, nameAdr; + PInfoRec recN; + String line, text = "", sNameType, newName, newType; + + if (lbCode->ItemIndex >= 1) + { + line = lbCode->Items->Strings[lbCode->ItemIndex]; + size = CodeGetTargetAdr(line, &nameAdr); + } + + if (IsValidImageAdr(nameAdr)) + { + pos = Adr2Pos(nameAdr); + recN = GetInfoRec(nameAdr); + //VMT + if (recN && recN->kind == ikVMT) return; + + //if (size == 4) + //{ + adr = *((DWORD*)(Code + pos)); + if (IsValidImageAdr(adr)) nameAdr = adr; + //} + } + else + { + nameAdr = CurProcAdr; + } + + pos = Adr2Pos(nameAdr); + recN = GetInfoRec(nameAdr); + if (recN && recN->HasName()) + { + text = recN->GetName(); + if (recN->type != "") text = recN->GetName() + ":" + recN->type; + } + + sNameType = InputDialogExec("Enter Name:Type (at " + Val2Str8(nameAdr) + ")", "Name:Type", text); + if (sNameType != "") + { + if (sNameType.Pos(":")) + { + newName = ExtractName(sNameType).Trim(); + newType = ExtractType(sNameType).Trim(); + } + else + { + newName = sNameType; + newType = ""; + } + + if (newName == "") return; + + //If call + if (pos >= 0 && IsFlagSet(cfProcStart, pos)) + { + if (!recN) recN = new InfoRec(pos, ikRefine); + recN->kind = ikProc; + recN->SetName(newName); + if (newType != "") + { + recN->kind = ikFunc; + recN->type = newType; + } + } + else + { + if (pos >= 0) + { + //Address points to Data + if (!recN) recN = new InfoRec(pos, ikUnknown); + recN->SetName(newName); + if (newType != "") recN->type = newType; + } + else + { + _idx = BSSInfos->IndexOf(Val2Str8(nameAdr)); + if (_idx != -1) + { + recN = (PInfoRec)BSSInfos->Objects[_idx]; + recN->SetName(newName); + recN->type = newType; + } + else + recN = AddToBSSInfos(nameAdr, newName, newType); + } + } + + RedrawCode(); + ShowUnitItems(GetUnit(CurUnitAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + ProjectModified = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miNameClick(TObject *Sender) +{ + NamePosition(); +} +//--------------------------------------------------------------------------- +TTreeNode* __fastcall TFMain_11011981::GetNodeByName(String AName) +{ + for (int n = 0; n < tvClassesFull->Items->Count; n++) + { + TTreeNode *node = tvClassesFull->Items->Item[n]; + String text = node->Text; + if (AName[1] != ' ') + { + if (text[1] != '<' && text[1] == AName[1] && text[2] == AName[2] && text.Pos(AName) == 1) return node; + } + else + { + if (text[1] != '<' && text.Pos(AName)) return node; + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ClearTreeNodeMap() +{ + tvClassMap.clear(); +} +//--------------------------------------------------------------------------- +TTreeNode* __fastcall TFMain_11011981::FindTreeNodeByName(const String& name) +{ + TTreeNodeNameMap::const_iterator it = tvClassMap.find(name); + if (it != tvClassMap.end()) return it->second; + + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AddTreeNodeWithName(TTreeNode* node, const String& name) +{ + tvClassMap[name] = node; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowClassViewer(DWORD VmtAdr) +{ + bool vmtProc; + WORD _dx, _bx, _si; + int cnt, vmtOfs, _pos; + DWORD parentAdr, adr = VmtAdr, vAdr, iAdr; + DWORD vmtAdresses[1024]; + String SelName = GetClsName(VmtAdr), line, name; + TTreeNode* selNode = 0; + TTreeNode* node = 0; + PInfoRec recN; + PMethodRec recM; + DISINFO disInfo; + + if (SelName == "" || !IsValidImageAdr(VmtAdr)) return; + + if (!tsClassView->Enabled) return; + + if (ClassTreeDone) + { + node = GetNodeByName(SelName + " #" + Val2Str8(adr) + " Sz="); + if (node) + { + node->Selected = true; + node->Expanded = true; + tvClassesFull->TopItem = node; + } + } + + TList *fieldsList = new TList; + TStringList *tmpList = new TStringList; + tmpList->Sorted = false; + + tvClassesShort->Items->Clear(); node = 0; + + for (int n = 0;; n++) + { + parentAdr = GetParentAdr(adr); + vmtAdresses[n] = adr; + if (!parentAdr) + { + while (n >= 0) + { + adr = vmtAdresses[n]; n--; + String className = GetClsName(adr); + int m, size = GetClassSize(adr); if (DelphiVersion >= 2009) size += 4; + + String text = className + " #" + Val2Str8(adr) + " Sz=" + Val2Str0(size); + + if (!node) //Root + node = tvClassesShort->Items->Add(0, text); + else + node = tvClassesShort->Items->AddChild(node, text); + + if (adr == VmtAdr && SameText(className, SelName)) selNode = node; + + //Interfaces + int intfsNum = LoadIntfTable(adr, tmpList); + if (intfsNum) + { + for (m = 0; m < intfsNum; m++) + { + String item = tmpList->Strings[m]; + sscanf(item.c_str(), "%lX", &vAdr); + if (IsValidCodeAdr(vAdr)) + { + int pos = item.Pos(' '); + TTreeNode* intfsNode = tvClassesShort->Items->AddChild(node, " " + item.SubString(pos + 1, item.Length())); + cnt = 0; + pos = Adr2Pos(vAdr); + for (int v = 0;;v += 4) + { + if (IsFlagSet(cfVTable, pos)) cnt++; + if (cnt == 2) break; + iAdr = *((DWORD*)(Code + pos)); + DWORD _adr = iAdr; + _pos = Adr2Pos(_adr); + vmtProc = false; vmtOfs = 0; + _dx = 0; _bx = 0; _si = 0; + while (1) + { + int instrlen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &disInfo, 0); + if ((disInfo.OpType[0] == otMEM || disInfo.OpType[1] == otMEM) && + disInfo.BaseReg != 20)//to exclude instruction "xchg reg, [esp]" + { + vmtOfs = disInfo.Offset; + } + if (disInfo.OpType[0] == otREG && disInfo.OpType[1] == otIMM) + { + if (disInfo.OpRegIdx[0] == 10)//dx + _dx = disInfo.Immediate; + else if (disInfo.OpRegIdx[0] == 11)//bx + _bx = disInfo.Immediate; + else if (disInfo.OpRegIdx[0] == 14)//si + _si = disInfo.Immediate; + } + if (disInfo.Call) + { + recN = GetInfoRec(disInfo.Immediate); + if (recN) + { + if (recN->SameName("@CallDynaInst") || + recN->SameName("@CallDynaClass")) + { + if (DelphiVersion <= 5) + GetDynaInfo(adr, _bx, &iAdr); + else + GetDynaInfo(adr, _si, &iAdr); + break; + } + else if (recN->SameName("@FindDynaInst") || + recN->SameName("@FindDynaClass")) + { + GetDynaInfo(adr, _dx, &iAdr); + break; + } + } + } + if (disInfo.Branch && !disInfo.Conditional) + { + if (IsValidImageAdr(disInfo.Immediate)) + { + iAdr = disInfo.Immediate; + } + else + { + vmtProc = true; + iAdr = *((DWORD*)(Code + Adr2Pos(VmtAdr - cVmtSelfPtr + vmtOfs))); + recM = GetMethodInfo(VmtAdr, 'V', vmtOfs); + if (recM) name = recM->name; + } + break; + } + else if (disInfo.Ret) + { + vmtProc = true; + iAdr = *((DWORD*)(Code + Adr2Pos(VmtAdr - cVmtSelfPtr + vmtOfs))); + recM = GetMethodInfo(VmtAdr, 'V', vmtOfs); + if (recM) name = recM->name; + break; + } + _pos += instrlen; _adr += instrlen; + } + if (!vmtProc && IsValidImageAdr(iAdr)) + { + recN = GetInfoRec(iAdr); + if (recN && recN->HasName()) + name = recN->GetName(); + else + name = ""; + } + line = "I" + Val2Str4(v) + " #" + Val2Str8(iAdr); + if (name != "") line += " " + name; + tvClassesShort->Items->AddChild(intfsNode, line); + pos += 4; + } + } + else + { + TTreeNode* intfsNode = tvClassesShort->Items->AddChild(node, " " + item); + } + } + } + //Automated + int autoNum = LoadAutoTable(adr, tmpList); + if (autoNum) + { + TTreeNode* autoNode = tvClassesShort->Items->AddChild(node, ""); + for (m = 0; m < autoNum; m++) + { + tvClassesShort->Items->AddChild(autoNode, tmpList->Strings[m]); + } + } + //Fields + int fieldsNum = LoadFieldTable(adr, fieldsList); + if (fieldsNum) + { + TTreeNode* fieldsNode = tvClassesShort->Items->AddChild(node, ""); + for (m = 0; m < fieldsNum; m++) + { + PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[m]; + text = Val2Str5(fInfo->Offset) + " "; + if (fInfo->Name != "") + text += fInfo->Name; + else + text += "?"; + text += ":"; + if (fInfo->Type != "") + text += TrimTypeName(fInfo->Type); + else + text += "?"; + + tvClassesShort->Items->AddChild(fieldsNode, text); + } + } + //Events + int methodsNum = LoadMethodTable(adr, tmpList); + if (methodsNum) + { + tmpList->Sort(); + TTreeNode* methodsNode = tvClassesShort->Items->AddChild(node, ""); + for (m = 0; m < methodsNum; m++) + { + tvClassesShort->Items->AddChild(methodsNode, tmpList->Strings[m]); + } + } + int dynamicsNum = LoadDynamicTable(adr, tmpList); + if (dynamicsNum) + { + tmpList->Sort(); + TTreeNode* dynamicsNode = FMain_11011981->tvClassesShort->Items->AddChild(node, ""); + for (m = 0; m < dynamicsNum; m++) + { + tvClassesShort->Items->AddChild(dynamicsNode, tmpList->Strings[m]); + } + } + //Virtual + int virtualsNum = LoadVirtualTable(adr, tmpList); + if (virtualsNum) + { + TTreeNode* virtualsNode = tvClassesShort->Items->AddChild(node, ""); + for (m = 0; m < virtualsNum; m++) + { + tvClassesShort->Items->AddChild(virtualsNode, tmpList->Strings[m]); + } + } + } + if (selNode) + { + selNode->Selected = true; + selNode->Expand(true); + tvClassesShort->TopItem = selNode; + } + break; + } + adr = parentAdr; + } + + delete fieldsList; + delete tmpList; + + pcWorkArea->ActivePage = tsClassView; + if (!rgViewerMode->ItemIndex) + { + tvClassesFull->BringToFront(); + //if (tvClassesFull->CanFocus()) ActiveControl = tvClassesFull; + } + else + { + tvClassesShort->BringToFront(); + //if (tvClassesShort->CanFocus()) ActiveControl = tvClassesShort; + } +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadIntfTable(DWORD adr, TStringList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->interfaces) + { + for (int n = 0; n < recN->vmtInfo->interfaces->Count; n++) + { + dstList->Add(recN->vmtInfo->interfaces->Strings[n]); + } + } + dstList->Sort(); + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadAutoTable(DWORD adr, TStringList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'A') + { + String line = "A" + Val2Str4(recM->id) + " #" + Val2Str8(recM->address) + " " + recM->name; + dstList->Add(line); + } + } + } + dstList->Sort(); + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadFieldTable(DWORD adr, TList* dstList) +{ + dstList->Clear(); + DWORD parentSize = GetParentSize(adr); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->fields) + { + for (int n = 0; n < recN->vmtInfo->fields->Count; n++) + { + PFIELDINFO fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; + if (fInfo->Offset >= parentSize) + { + bool exist = false; + for (int m = 0; m < dstList->Count; m++) + { + PFIELDINFO fInfo1 = (PFIELDINFO)dstList->Items[m]; + if (fInfo1->Offset == fInfo->Offset) + { + exist = true; + break; + } + } + if (!exist) dstList->Add((void*)fInfo); + } + } + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadAllFields(DWORD adr, TList* dstList) +{ + while (1) + { + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->fields) + { + for (int n = 0; n < recN->vmtInfo->fields->Count; n++) + { + PFIELDINFO fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; + bool exist = false; + for (int m = 0; m < dstList->Count; m++) + { + PFIELDINFO fInfo1 = (PFIELDINFO)dstList->Items[m]; + if (fInfo1->Offset == fInfo->Offset) + { + exist = true; + break; + } + } + if (!exist) dstList->Add((void*)fInfo); + } + } + adr = GetParentAdr(adr); + if (!adr) break; + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadMethodTable(DWORD adr, TList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + String className = GetClsName(adr) + "."; + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'M') + { + if (recM->name.Pos(".") == 0 || recM->name.Pos(className) == 1) dstList->Add((void*)recM); + } + } + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadMethodTable(DWORD adr, TStringList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'M') + { + String line = "#" + Val2Str8(recM->address) + " " + recM->name; + dstList->Add(line); + } + } + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadDynamicTable(DWORD adr, TList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + String className = GetClsName(adr) + "."; + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'D') + { + if (recM->name.Pos(".") == 0 || recM->name.Pos(className) == 1) dstList->Add((void*)recM); + } + } + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadDynamicTable(DWORD adr, TStringList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'D') + { + String line = "D" + Val2Str4(recM->id) + " #" + Val2Str8(recM->address) + " " + recM->name; + dstList->Add(line); + } + } + dstList->Sort(); + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadVirtualTable(DWORD adr, TList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + String className = GetClsName(adr) + "."; + recN->vmtInfo->methods->Sort(MethodsCmpFunction); + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'V') + { + //if (recM->name.Pos(".") == 0 || recM->name.Pos(className) == 1) dstList->Add((void*)recM); + dstList->Add((void*)recM); + } + } + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadVirtualTable(DWORD adr, TStringList* dstList) +{ + dstList->Clear(); + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + recN->vmtInfo->methods->Sort(MethodsCmpFunction); + for (int n = 0; n < recN->vmtInfo->methods->Count; n++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; + if (recM->kind == 'V')// && recM->id >= -4) + { + String line = ""; + PInfoRec recN1 = GetInfoRec(recM->address); + + if (recM->id < 0) + line += "-" + Val2Str4(-(recM->id)); + else + line += "V" + Val2Str4(recM->id); + + line += " #" + Val2Str8(recM->address); + if (recM->name != "") + { + line += + " " + recM->name; + if (recN1 && recN1->HasName() && !recN1->SameName(recM->name)) + { + //Change "@AbstractError" to "abstract" + if (SameText(recN1->GetName(), "@AbstractError")) + line += " (abstract)"; + else + line += " (" + recN1->GetName() + ")"; + } + } + else + { + if (recN1 && recN1->HasName()) line += " " + recN1->GetName(); + } + + dstList->Add(line); + } + } + } + return dstList->Count; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miViewProtoClick(TObject *Sender) +{ + int Idx; + DWORD Adr; + PInfoRec recN; + MProcInfo pInfo; + String item; + DISINFO DisInfo; + + if (lbCode->ItemIndex <= 0) return; + + item = lbCode->Items->Strings[lbCode->ItemIndex]; + sscanf(item.c_str() + 1, "%lX", &Adr); + int instrlen = Disasm.Disassemble(Code + Adr2Pos(Adr), (__int64)Adr, &DisInfo, 0); + if (!instrlen) return; + + String proto = ""; + if (DisInfo.Call) + { + //Àäðåñ çàäàí ÿâíî + if (IsValidCodeAdr(DisInfo.Immediate)) + { + recN = GetInfoRec(DisInfo.Immediate); + if (recN) proto = recN->MakePrototype(DisInfo.Immediate, true, false, false, true, true); + } + //Àäðåñ íå çàäàí, ïðîáóåì ïè-êîä + else + { + recN = GetInfoRec(Adr); + if (recN && recN->picode && IsValidCodeAdr(recN->picode->Ofs.Address)) + { + if (KnowledgeBase.GetProcInfo(recN->picode->Name.c_str(), INFO_ARGS, &pInfo, &Idx)) + proto = KnowledgeBase.GetProcPrototype(&pInfo); + } + } + } + if (proto != "") + { + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->Caption = "Prototype"; + FStringInfo_11011981->memStringInfo->Lines->Add(proto); + FStringInfo_11011981->ShowModal(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowCXrefsClick(TObject *Sender) +{ + if (lbCXrefs->Visible) + { + ShowCXrefs->BevelOuter = bvRaised; + lbCXrefs->Visible = false; + } + else + { + ShowCXrefs->BevelOuter = bvLowered; + lbCXrefs->Visible = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::bCodePrevClick(TObject *Sender) +{ + //first add to array current subroutine info (for ->) + if (CodeHistoryPtr == CodeHistorySize - 1) + { + CodeHistorySize += HISTORY_CHUNK_LENGTH; + CodeHistory.Length = CodeHistorySize; + } + + PROCHISTORYREC rec; + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + memmove(&CodeHistory[CodeHistoryPtr + 1], &rec, sizeof(PROCHISTORYREC)); + //next pop from array + PPROCHISTORYREC prec = CodeHistoryPop(); + if (prec) ShowCode(prec->adr, prec->itemIdx, prec->xrefIdx, prec->topIdx); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::bCodeNextClick(TObject *Sender) +{ + PROCHISTORYREC rec; + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + + CodeHistoryPtr++; + memmove(&CodeHistory[CodeHistoryPtr], &rec, sizeof(PROCHISTORYREC)); + + PPROCHISTORYREC prec = &CodeHistory[CodeHistoryPtr + 1]; + ShowCode(prec->adr, prec->itemIdx, prec->xrefIdx, prec->topIdx); + + bCodePrev->Enabled = (CodeHistoryPtr >= 0); + bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::CodeHistoryPush(PPROCHISTORYREC rec) +{ + if (CodeHistoryPtr == CodeHistorySize - 1) + { + CodeHistorySize += HISTORY_CHUNK_LENGTH; + CodeHistory.Length = CodeHistorySize; + } + + CodeHistoryPtr++; + memmove(&CodeHistory[CodeHistoryPtr], rec, sizeof(PROCHISTORYREC)); + + CodeHistoryMax = CodeHistoryPtr; + bCodePrev->Enabled = (CodeHistoryPtr >= 0); + bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); +} +//--------------------------------------------------------------------------- +PPROCHISTORYREC __fastcall TFMain_11011981::CodeHistoryPop() +{ + PPROCHISTORYREC prec = 0; + if (CodeHistoryPtr >= 0) + { + prec = &CodeHistory[CodeHistoryPtr]; + CodeHistoryPtr--; + } + bCodePrev->Enabled = (CodeHistoryPtr >= 0); + bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); + return prec; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::tvClassesDblClick(TObject *Sender) +{ + int k, m, n; + TTreeView* tv; + PROCHISTORYREC rec; + + if (ActiveControl == tvClassesFull || ActiveControl == tvClassesShort) + tv = (TTreeView*)ActiveControl; + + TTreeNode *node = tv->Selected; + if (node) + { + DWORD adr; + String line = node->Text; + int pos = line.Pos("#"); + //Given address + if (pos && !line.Pos("Sz=")) + { + sscanf(line.c_str() + pos, "%lX", &adr); + if (IsValidCodeAdr(adr)) + { + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(adr, 0, -1, -1); + CodeHistoryPush(&rec); + } + return; + } + //Given field type + if (line.Pos(":")) + { + //Line contains shadow name + if (LineContainsShadowName(line)) + { + int adrOfs = GetAdrOfsFromShadowName(line); + if (adrOfs != -1) + { + String adrStr = line.SubString(adrOfs, line.Length() - adrOfs + 1); + adr = StrToInt("$" + adrStr); + FTypeInfo_11011981->ShowRTTI(adr);//SHADOW + return; + } + } + String typeName = ExtractType(line); + //Type given as Unit.TypeName + if (typeName.Pos(".")) typeName = ExtractProcName(typeName); + + adr = GetClassAdr(typeName); + if (IsValidImageAdr(adr)) + { + ShowClassViewer(adr); + } + else + { + WORD* uses = KnowledgeBase.GetTypeUses(typeName.c_str()); + int Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, typeName.c_str()); + if (Idx != -1) + { + Idx = KnowledgeBase.TypeOffsets[Idx].NamId; + MTypeInfo tInfo; + if (KnowledgeBase.GetTypeInfo(Idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS, &tInfo)) + { + FTypeInfo_11011981->ShowKbInfo(&tInfo); + //as delete tInfo; + } + } + if (uses) delete[] uses; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::tvClassesShortKeyDown(TObject *Sender, + WORD &Key, TShiftState Shift) +{ + if (Key == VK_RETURN) tvClassesDblClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmVMTsPopup(TObject *Sender) +{ + bool b; + if (ActiveControl == tvClassesFull) + { + b = (tvClassesFull->Items->Count != 0); + miSearchVMT->Visible = b; + miCollapseAll->Visible = b; + miEditClass->Visible = false; + return; + } + if (ActiveControl == tvClassesShort) + { + b = (tvClassesShort->Items->Count != 0); + miSearchVMT->Visible = b; + miCollapseAll->Visible = b; + miEditClass->Visible = !AnalyzeThread && b && tvClassesShort->Selected; + return; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miViewClassClick(TObject *Sender) +{ + String sName = InputDialogExec("Enter Name of Type", "Name:", ""); + if (sName != "") ShowClassViewer(GetClassAdr(sName)); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchVMTClick(TObject *Sender) +{ + WhereSearch = SEARCH_CLASSVIEWER; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < VMTsSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(VMTsSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (ActiveControl == tvClassesFull) + { + if (tvClassesFull->Selected) + TreeSearchFrom = tvClassesFull->Selected; + else + TreeSearchFrom = tvClassesFull->Items->Item[0]; + } + else if (ActiveControl == tvClassesShort) + { + if (tvClassesShort->Selected) + BranchSearchFrom = tvClassesShort->Selected; + else + BranchSearchFrom = tvClassesShort->Items->Item[0]; + } + + VMTsSearchText = FindDlg_11011981->cbText->Text; + if (VMTsSearchList->IndexOf(VMTsSearchText) == -1) VMTsSearchList->Add(VMTsSearchText); + FindText(VMTsSearchText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCollapseAllClick(TObject *Sender) +{ + TTreeView* tv; + if (ActiveControl == tvClassesFull || ActiveControl == tvClassesShort) + { + tv = (TTreeView*)ActiveControl; + tv->Items->BeginUpdate(); + TTreeNode* rootNode = tv->Items->Item[0]; + const int cnt = rootNode->Count; + for (int n = 0; n < cnt; n++) + { + TTreeNode* node = rootNode->Item[n]; + if (node->HasChildren && node->Expanded) node->Collapse(true); + } + tv->Items->EndUpdate(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miEditClassClick(TObject *Sender) +{ + if (ActiveControl == tvClassesShort) + { + TTreeNode* node = tvClassesShort->Selected; + if (node) + { + int FieldOfs = -1; + if (!node->Text.Pos("#")) + sscanf(node->Text.c_str(), "%lX", &FieldOfs); + while (node) + { + int pos = node->Text.Pos("#"); + //Óêàçàí àäðåñ + if (pos && node->Text.Pos("Sz=")) + { + DWORD vmtAdr; + sscanf(node->Text.c_str() + pos, "%lX", &vmtAdr); + if (IsValidImageAdr(vmtAdr)) + { + FEditFieldsDlg_11011981->VmtAdr = vmtAdr; + FEditFieldsDlg_11011981->FieldOffset = FieldOfs; + if (FEditFieldsDlg_11011981->Visible) FEditFieldsDlg_11011981->Close(); + FEditFieldsDlg_11011981->FormStyle = fsStayOnTop; + FEditFieldsDlg_11011981->Show(); + return; + } + } + node = node->GetPrev(); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopyCodeClick(TObject *Sender) +{ + Copy2Clipboard(lbCode->Items, 1, true); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbFormsDblClick(TObject *Sender) +{ + int n, m; + + TDfm *dfm = (TDfm*)ResInfo->FormList->Items[lbForms->ItemIndex]; + switch (rgViewFormAs->ItemIndex) + { + //As Text + case 0: + FExplorer_11011981->tsCode->TabVisible = false; + FExplorer_11011981->tsData->TabVisible = false; + FExplorer_11011981->tsString->TabVisible = false; + FExplorer_11011981->tsText->TabVisible = true; + FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsText; + ResInfo->GetFormAsText(dfm, FExplorer_11011981->lbText->Items); + FExplorer_11011981->ShowModal(); + break; + //As Form + case 1: + if (dfm->Open != 2) + { + //Åñëè åñòü îòêðûòûå ôîðìû, çàêðûâàåì èõ + ResInfo->CloseAllForms(); + + ShowDfm(dfm); + } + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowDfm(TDfm* dfm) +{ + if (!dfm) + return; + + //if inherited find parent form + if ((dfm->Flags & FF_INHERITED) && !dfm->ParentDfm) + dfm->ParentDfm = ResInfo->GetParentDfm(dfm); + + dfm->Loader = new IdrDfmLoader(0); + dfm->Form = dfm->Loader->LoadForm(dfm->MemStream, dfm); + delete dfm->Loader; + dfm->Loader = 0; + + if (dfm->Form) + { + PUnitRec recU = GetUnit(GetClassAdr(dfm->ClassName)); + if (recU) + { + int stringLen = sprintf(StringBuf, "[#%03d] %s", recU->iniOrder, dfm->Form->Caption.c_str()); + dfm->Form->Caption = String(StringBuf, stringLen); + } + dfm->Open = 2; + dfm->Form->Show(); + + //if (!AnalyzeThread) + // sb->Panels->Items[0]->Text = "Press F11 to open form controls tree"; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbFormsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + if (lbForms->ItemIndex >= 0 && Key == VK_RETURN) lbFormsDblClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbCodeKeyDown(TObject *Sender, + WORD &Key, TShiftState Shift) +{ + switch (Key) + { + case VK_RETURN: + lbCodeDblClick(Sender); + break; + case VK_ESCAPE: + bCodePrevClick(Sender); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::CleanProject() +{ + int n; + PInfoRec recN; + + if (Image) + { + delete[] Image; + Image = 0; + } + if (Flags) + { + delete[] Flags; + Flags = 0; + } + if (Infos) + { + for (n = 0; n < TotalSize; n++) + { + recN = GetInfoRec(Pos2Adr(n)); + if (recN) delete recN; + } + delete[] Infos; + Infos = 0; + } + if (BSSInfos) + { + for (n = 0; n < BSSInfos->Count; n++) + { + recN = (PInfoRec)BSSInfos->Objects[n]; + if (recN) delete recN; + } + + delete BSSInfos; + BSSInfos = 0; + } + + for (n = 0; n < SegmentList->Count; n++) + { + PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; + delete segInfo; + } + SegmentList->Clear(); + + for (n = 0; n < ExpFuncList->Count; n++) + { + PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[n]; + delete recE; + } + ExpFuncList->Clear(); + + for (n = 0; n < ImpFuncList->Count; n++) + { + PImportNameRec recI = (PImportNameRec)ImpFuncList->Items[n]; + delete recI; + } + ImpFuncList->Clear(); + + VmtList->Clear(); + + for (n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + delete recU; + } + Units->Clear(); + UnitsNum = 0; + + for (n = 0; n < OwnTypeList->Count; n++) + { + PTypeRec recT = (PTypeRec)OwnTypeList->Items[n]; + delete recT; + } + OwnTypeList->Clear(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::CloseProject() +{ + CleanProject(); + + ResInfo->CloseAllForms(); + + for (int n = 0; n < ResInfo->FormList->Count; n++) + { + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + delete dfm; + } + + ResInfo->FormList->Clear(); + ResInfo->Aliases->Clear(); + if (ResInfo->hFormPlugin) + { + FreeLibrary(ResInfo->hFormPlugin); + ResInfo->hFormPlugin = 0; + } + ResInfo->Counter = 0; + + OwnTypeList->Clear(); + + UnitsSearchList->Clear(); + RTTIsSearchList->Clear(); + UnitItemsSearchList->Clear(); + VMTsSearchList->Clear(); + FormsSearchList->Clear(); + StringsSearchList->Clear(); + NamesSearchList->Clear(); + + CodeHistoryPtr = -1; + CodeHistoryMax = CodeHistoryPtr; + CodeHistory.Length = 0; + + KnowledgeBase.Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::tvClassesFullClick(TObject *Sender) +{ + TreeSearchFrom = tvClassesFull->Selected; + WhereSearch = SEARCH_CLASSVIEWER; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::tvClassesShortClick(TObject *Sender) +{ + BranchSearchFrom = tvClassesShort->Selected; + WhereSearch = SEARCH_CLASSVIEWER; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FindText(String Text) +{ + int n, pos, idx = -1; + String line, findText, msg; + TTreeNode* node; + TTreeView* tv; + + if (Text == "") return; + + msg = "Search string \"" + Text + "\" not found"; + + switch (WhereSearch) + { + case SEARCH_UNITS: + for (n = UnitsSearchFrom; n < lbUnits->Items->Count; n++) + { + if (AnsiContainsText(lbUnits->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + if (idx == -1) + { + for (n = 0; n < UnitsSearchFrom; n++) + { + if (AnsiContainsText(lbUnits->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + } + if (idx != -1) + { + UnitsSearchFrom = (idx < lbUnits->Items->Count - 1) ? idx + 1 : 0; + lbUnits->ItemIndex = idx; + lbUnits->SetFocus(); + } + else + { + ShowMessage(msg); + } + break; + case SEARCH_UNITITEMS: + for (n = UnitItemsSearchFrom; n < lbUnitItems->Items->Count; n++) + { + if (AnsiContainsText(lbUnitItems->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + if (idx == -1) + { + for (n = 0; n < UnitItemsSearchFrom; n++) + { + if (AnsiContainsText(lbUnitItems->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + } + if (idx != -1) + { + UnitItemsSearchFrom = (idx < lbUnitItems->Items->Count) ? idx + 1 : 0; + lbUnitItems->ItemIndex = idx; + lbUnitItems->SetFocus(); + } + else + { + ShowMessage(msg); + } + break; + case SEARCH_RTTIS: + for (n = RTTIsSearchFrom; n < lbRTTIs->Items->Count; n++) + { + if (AnsiContainsText(lbRTTIs->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + if (idx == -1) + { + for (n = 0; n < RTTIsSearchFrom; n++) + { + if (AnsiContainsText(lbRTTIs->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + } + if (idx != -1) + { + RTTIsSearchFrom = (idx < lbRTTIs->Items->Count - 1) ? idx + 1 : 0; + lbRTTIs->ItemIndex = idx; + lbRTTIs->SetFocus(); + } + else + { + ShowMessage(msg); + } + break; + case SEARCH_FORMS: + for (n = FormsSearchFrom; n < lbForms->Items->Count; n++) + { + if (AnsiContainsText(lbForms->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + if (idx == -1) + { + for (n = 0; n < FormsSearchFrom; n++) + { + if (AnsiContainsText(lbForms->Items->Strings[n], Text)) + { + idx = n; + break; + } + } + } + if (idx != -1) + { + FormsSearchFrom = (idx < lbForms->Items->Count - 1) ? idx + 1 : 0; + lbForms->ItemIndex = idx; + lbForms->SetFocus(); + } + else + { + ShowMessage(msg); + } + break; + case SEARCH_CLASSVIEWER: + if (!rgViewerMode->ItemIndex) + { + node = TreeSearchFrom; + while (node) + { + line = node->Text; + //Skip <> + if (line[1] != '<' && AnsiContainsText(line, Text)) + { + idx = 0; + break; + } + node = node->GetNext(); + } + if (idx == -1 && tvClassesFull->Items->Count) + { + node = tvClassesFull->Items->Item[0]; + while (node != TreeSearchFrom) + { + line = node->Text; + //Skip <> + if (line[1] != '<' && AnsiContainsText(line, Text)) + { + idx = 0; + break; + } + node = node->GetNext(); + } + } + if (idx != -1) + { + TreeSearchFrom = (node->GetNext()) ? node->GetNext() : tvClassesFull->Items->Item[0]; + node->Selected = true; + node->Expanded = true; + tvClassesFull->Show(); + } + else + { + ShowMessage(msg); + } + } + else + { + node = BranchSearchFrom; + while (node) + { + line = node->Text; + //Skip <> + if (line[1] != '<' && AnsiContainsText(line, Text)) + { + idx = 0; + break; + } + node = node->GetNext(); + } + if (idx == -1 && tvClassesShort->Items->Count) + { + node = tvClassesShort->Items->Item[0]; + while (node != BranchSearchFrom) + { + line = node->Text; + //Skip <> + if (line[1] != '<' && AnsiContainsText(line, Text)) + { + idx = 0; + break; + } + node = node->GetNext(); + } + } + if (idx != -1) + { + BranchSearchFrom = (node->GetNext()) ? node->GetNext() : tvClassesShort->Items->Item[0]; + node->Selected = true; + node->Expanded = true; + tvClassesShort->Show(); + } + else + { + ShowMessage(msg); + } + } + break; + case SEARCH_STRINGS: + for (n = StringsSearchFrom; n < lbStrings->Items->Count; n++) + { + line = lbStrings->Items->Strings[n]; + pos = line.Pos("'"); + line = line.SubString(pos + 1, line.Length() - pos); + if (AnsiContainsText(line, Text)) + { + idx = n; + break; + } + } + if (idx == -1) + { + for (n = 0; n < StringsSearchFrom; n++) + { + line = lbStrings->Items->Strings[n]; + pos = line.Pos("'"); + line = line.SubString(pos + 1, line.Length() - pos); + if (AnsiContainsText(line, Text)) + { + idx = n; + break; + } + } + } + if (idx != -1) + { + StringsSearchFrom = (idx < lbStrings->Items->Count - 1) ? idx + 1 : 0; + lbStrings->ItemIndex = idx; + lbStrings->SetFocus(); + } + else + { + ShowMessage(msg); + } + break; + case SEARCH_NAMES: + for (n = NamesSearchFrom; n < lbNames->Items->Count; n++) + { + line = lbNames->Items->Strings[n]; + if (AnsiContainsText(line, Text)) + { + idx = n; + break; + } + } + if (idx == -1) + { + for (n = 0; n < NamesSearchFrom; n++) + { + line = lbNames->Items->Strings[n]; + if (AnsiContainsText(line, Text)) + { + idx = n; + break; + } + } + } + if (idx != -1) + { + NamesSearchFrom = (idx < lbNames->Items->Count - 1) ? idx + 1 : 0; + lbNames->ItemIndex = idx; + lbNames->SetFocus(); + } + else + { + ShowMessage(msg); + } + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbFormsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if (lbForms->CanFocus()) ActiveControl = lbForms; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbCodeMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if (lbCode->CanFocus()) ActiveControl = lbCode; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::tvClassesFullMouseMove( + TObject *Sender, TShiftState Shift, int X, int Y) +{ + if (tvClassesFull->CanFocus()) ActiveControl = tvClassesFull; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::tvClassesShortMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if (tvClassesShort->CanFocus()) ActiveControl = tvClassesShort; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::rgViewerModeClick(TObject *Sender) +{ + if (!rgViewerMode->ItemIndex) + tvClassesFull->BringToFront(); + else + tvClassesShort->BringToFront(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miClassTreeBuilderClick(TObject *Sender) +{ + miLoadFile->Enabled = false; + miOpenProject->Enabled = false; + miMRF->Enabled = false; + miSaveProject->Enabled = false; + miSaveDelphiProject->Enabled = false; + miMapGenerator->Enabled = false; + miCommentsGenerator->Enabled = false; + miIDCGenerator->Enabled = false; + miHiewGenerator->Enabled = false; + miLister->Enabled = false; + miClassTreeBuilder->Enabled = false; + miKBTypeInfo->Enabled = false; + miCtdPassword->Enabled = false; + miHex2Double->Enabled = false; + + FProgressBar->Show(); + + AnalyzeThread = new TAnalyzeThread(FMain_11011981, FProgressBar, false); + AnalyzeThread->Resume(); +} +//--------------------------------------------------------------------------- +//INI FILE +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::IniFileRead() +{ + int n, m, pos, version; String str, filename, ident; + TMenuItem *item; + TIniFile *iniFile; + TFont *_font; + TMonitor *_monitor; + + iniFile = new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); + + CodePage = iniFile->ReadInteger("Settings", "CodePage", 1251); + _font = new TFont; + _font->Name = iniFile->ReadString("Settings", "FontName", "Fixedsys"); + _font->Charset = iniFile->ReadInteger("Settings", "FontCharset", 1); + _font->Size = iniFile->ReadInteger("Settings", "FontSize", 9); + _font->Color = iniFile->ReadInteger("Settings", "FontColor", 0); + if (iniFile->ReadBool("Settings", "FontBold", False)) + _font->Style = _font->Style << fsBold; + if (iniFile->ReadBool("Settings", "FontItalic", False)) + _font->Style = _font->Style << fsItalic; + SetupAllFonts(_font); + delete _font; + + WrkDir = iniFile->ReadString("MainForm", "WorkingDir", AppDir); + + for (n = 0; n < Screen->MonitorCount; n++) + { + _monitor = Screen->Monitors[n]; + if (_monitor->Primary) + { + Left = iniFile->ReadInteger("MainForm", "Left", _monitor->WorkareaRect.Left); + Top = iniFile->ReadInteger("MainForm", "Top", _monitor->WorkareaRect.Top); + Width = iniFile->ReadInteger("MainForm", "Width", _monitor->WorkareaRect.Width()); + Height = iniFile->ReadInteger("MainForm", "Height", _monitor->WorkareaRect.Height()); + break; + } + } + pcInfo->Width = iniFile->ReadInteger("MainForm", "LeftWidth", Width / 5); + pcInfo->ActivePage = tsUnits; + lbUnitItems->Height = iniFile->ReadInteger("MainForm", "BottomHeight", Height / 8); + //Most Recent Files + + for (n = 0, m = 0; n < 8; n++) + { + ident = "File" + String(n + 1); + str = iniFile->ReadString("Recent Executable Files", ident, ""); + pos = str.LastDelimiter(","); + if (pos) + { + filename = str.SubString(2, pos - 3); //Modified by ZGL + version = str.SubString(pos + 1, str.Length() - pos).ToInt(); + } + else + { + filename = str; + version = -1; + } + if (FileExists(filename)) + { + item = miMRF->Items[m]; m++; + item->Caption = filename; + item->Tag = version; + item->Visible = (filename != ""); + item->Enabled = true; + } + else + { + iniFile->DeleteKey("Recent Executable Files", ident); + } + } + for (n = 9, m = 9; n < 17; n++) + { + ident = "File" + String(n - 8); + filename = iniFile->ReadString("Recent Project Files", ident, ""); + if (FileExists(filename)) + { + item = miMRF->Items[m]; m++; + item->Caption = filename; + item->Tag = 0; + item->Visible = (item->Caption != ""); + item->Enabled = true; + } + else + { + iniFile->DeleteKey("Recent Project Files", ident); + } + } + delete iniFile; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::IniFileWrite() +{ + TIniFile *iniFile = new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); + iniFile->WriteInteger("Settings", "CodePage", CodePage); + iniFile->WriteString("Settings", "FontName", lbCode->Font->Name); + iniFile->WriteInteger("Settings", "FontCharset", lbCode->Font->Charset); + iniFile->WriteInteger("Settings", "FontSize", lbCode->Font->Size); + iniFile->WriteInteger("Settings", "FontColor", lbCode->Font->Color); + iniFile->WriteBool("Settings", "FontBold", lbCode->Font->Style.Contains(fsBold)); + iniFile->WriteBool("Settings", "FontItalic", lbCode->Font->Style.Contains(fsItalic)); + + iniFile->WriteString("MainForm", "WorkingDir", WrkDir); + iniFile->WriteInteger("MainForm", "Left", Left); + iniFile->WriteInteger("MainForm", "Top", Top); + iniFile->WriteInteger("MainForm", "Width", Width); + iniFile->WriteInteger("MainForm", "Height", Height); + iniFile->WriteInteger("MainForm", "LeftWidth", pcInfo->Width); + iniFile->WriteInteger("MainForm", "BottomHeight", lbUnitItems->Height); + + //Delete all + int n; String ident; + for (n = 0; n < 8; n++) iniFile->DeleteKey("Recent Executable Files", "File" + String(n + 1)); + for (n = 9; n < 17; n++) iniFile->DeleteKey("Recent Executable Files", "File" + String(n - 8)); + + //Fill + for (n = 0; n < 8; n++) + { + TMenuItem *item = miMRF->Items[n]; + if (item->Visible && item->Enabled) iniFile->WriteString("Recent Executable Files", "File" + String(n + 1), "\"" + item->Caption + "\"," + String(item->Tag)); + } + for (n = 9; n < 17; n++) + { + TMenuItem *item = miMRF->Items[n]; + if (item->Visible && item->Enabled) iniFile->WriteString("Recent Project Files", "File" + String(n - 8), "\"" + item->Caption + "\""); + } + + delete iniFile; +} +//--------------------------------------------------------------------------- +//LOAD EXE AND IDP +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::IsExe(String FileName) +{ + IMAGE_DOS_HEADER DosHeader; + IMAGE_NT_HEADERS NTHeaders; + + FILE* f = fopen(FileName.c_str(), "rb"); + if (!f) return false; + + fseek(f, 0, SEEK_SET); + //IDD_ERR_NOT_EXECUTABLE + int readed = fread(&DosHeader, 1, sizeof(IMAGE_DOS_HEADER), f); + + if (readed != sizeof(IMAGE_DOS_HEADER) || + DosHeader.e_magic != IMAGE_DOS_SIGNATURE) + { + fclose(f); + return false; + } + + fseek(f, DosHeader.e_lfanew, SEEK_SET); + //IDD_ERR_NOT_PE_EXECUTABLE + readed = fread(&NTHeaders, 1, sizeof(IMAGE_NT_HEADERS), f); + fclose(f); + if (readed != sizeof(IMAGE_NT_HEADERS) || + NTHeaders.Signature != IMAGE_NT_SIGNATURE) + { + return false; + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::IsIdp(String FileName) +{ + char buf[13]; + + FILE* f = fopen(FileName.c_str(), "rb"); + if (!f) return false; + + fseek(f, 0, SEEK_SET); + fread(buf, 1, 12, f); buf[12] = 0; + fclose(f); + + if (!strcmp(buf, "IDR proj v.3")) return true; + return false; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miAutodetectVersionClick(TObject *Sender) +{ + LoadDelphiFile(0); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi2Click(TObject *Sender) +{ + LoadDelphiFile(2); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi3Click(TObject *Sender) +{ + LoadDelphiFile(3); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi4Click(TObject *Sender) +{ + LoadDelphiFile(4); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi5Click(TObject *Sender) +{ + LoadDelphiFile(5); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi6Click(TObject *Sender) +{ + LoadDelphiFile(6); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi7Click(TObject *Sender) +{ + LoadDelphiFile(7); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi2005Click(TObject *Sender) +{ + LoadDelphiFile(2005); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi2006Click(TObject *Sender) +{ + LoadDelphiFile(2006); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi2007Click(TObject *Sender) +{ + LoadDelphiFile(2007); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi2009Click(TObject *Sender) +{ + LoadDelphiFile(2009); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphi2010Click(TObject *Sender) +{ + LoadDelphiFile(2010); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphiXE1Click(TObject *Sender) +{ + LoadDelphiFile(2011); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphiXE2Click(TObject *Sender) +{ + LoadDelphiFile(2012); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphiXE3Click(TObject *Sender) +{ + LoadDelphiFile(2013); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miDelphiXE4Click(TObject *Sender) +{ + LoadDelphiFile(2014); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::LoadFile(String FileName, int version) +{ + if (ProjectModified) + { + int res = Application->MessageBox("Save active Project?", "Confirmation", MB_YESNOCANCEL); + if (res == IDCANCEL) return; + if (res == IDYES) + { + if (IDPFile == "") IDPFile = ChangeFileExt(SourceFile, ".idp"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "IDP|*.idp"; + SaveDlg->FileName = IDPFile; + + if (SaveDlg->Execute()) SaveProject(SaveDlg->FileName); + } + } + + if (IsExe(FileName)) + { + CloseProject(); + Init(); + LoadDelphiFile1(FileName, version, true, true); + } + else if (IsIdp(FileName)) + { + CloseProject(); + Init(); + OpenProject(FileName); + } + else + { + ShowMessage("File " + FileName + " is not executable or IDR project file"); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::LoadDelphiFile(int version) +{ + DoOpenDelphiFile(version, "", true, true); +} +//--------------------------------------------------------------------------- +//version: 0 for autodetect, else - exact version +// +void __fastcall TFMain_11011981::DoOpenDelphiFile(int version, String FileName, bool loadExp, bool loadImp) +{ + if (ProjectModified) + { + int res = Application->MessageBox("Save active Project?", "Confirmation", MB_YESNOCANCEL); + if (res == IDCANCEL) return; + if (res == IDYES) + { + if (IDPFile == "") IDPFile = ChangeFileExt(SourceFile, ".idp"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "IDP|*.idp"; + SaveDlg->FileName = IDPFile; + + if (SaveDlg->Execute()) SaveProject(SaveDlg->FileName); + } + } + if (FileName == "") + { + OpenDlg->InitialDir = WrkDir; + OpenDlg->FileName = ""; + OpenDlg->Filter = "EXE, DLL|*.exe;*.dll|All files|*.*"; + if (OpenDlg->Execute()) FileName = OpenDlg->FileName; + } + if (FileName != "") + { + if (!FileExists(FileName)) + { + ShowMessage("File " + FileName + " not exists"); + return; + } + CloseProject(); + Init(); + WrkDir = ExtractFileDir(FileName); + LoadDelphiFile1(FileName, version, loadExp, loadImp); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::LoadDelphiFile1(String FileName, int version, bool loadExp, bool loadImp) +{ + int pos, ver; + String dprName, KBFileName, msg; + + SourceFile = FileName; + FILE *f = fopen(FileName.c_str(), "rb"); + + Screen->Cursor = crHourGlass; + int res = LoadImage(f, version, loadExp, loadImp); + fclose(f); + + if (res <= 0) + { + if (!res) ShowMessage("LoadImage error"); + Screen->Cursor = crDefault; + return; + } + + FindExports(); + FindImports(); + + ResInfo->EnumResources(SourceFile); + ResInfo->ShowResources(lbForms); + tsForms->Enabled = (lbForms->Items->Count > 0); + + if (version == DELHPI_VERSION_AUTO) //Autodetect + { + DelphiVersion = GetDelphiVersion(); + if (DelphiVersion == 1) + { + Screen->Cursor = crDefault; + ShowMessage("File " + FileName + " is probably Delphi 4, 5, 6, 7, 2005, 2006 or 2007 file, try manual selection"); + FInputDlg_11011981->Caption = "Enter number of version (4, 5, 6, 7, 2005, 2006 or 2007)"; + FInputDlg_11011981->edtName->Text = ""; + if (FInputDlg_11011981->ShowModal() == mrCancel) + { + CleanProject(); + return; + } + if (!TryStrToInt(FInputDlg_11011981->edtName->Text.Trim(), DelphiVersion)) + { + CleanProject(); + return; + } + } + if (DelphiVersion == -1) + { + Screen->Cursor = crDefault; + ShowMessage("File " + FileName + " is probably not Delphi file"); + CleanProject(); + return; + } + } + else + DelphiVersion = version; + Screen->Cursor = crDefault; + + UserKnowledgeBase = false; + if (Application->MessageBox("Use native Knowledge Base?", "Knowledge Base kind selection", MB_YESNO) == IDNO) + { + OpenDlg->InitialDir = WrkDir; + OpenDlg->FileName = ""; + OpenDlg->Filter = "BIN|*.bin|All files|*.*"; + if (OpenDlg->Execute()) + { + KBFileName = OpenDlg->FileName; + UserKnowledgeBase = true; + } + } + else + KBFileName = AppDir + "kb" + DelphiVersion + ".bin"; + + if (KBFileName == "") + { + ShowMessage("Knowledge Base file not selected"); + CleanProject(); + return; + } + + Screen->Cursor = crHourGlass; + res = KnowledgeBase.Open(KBFileName.c_str()); + + if (!res) + { + Screen->Cursor = crDefault; + ShowMessage("Cannot open Knowledge Base file " + String(KBFileName) + " (may be incorrect Version)"); + CleanProject(); + return; + } + + SetVmtConsts(DelphiVersion); + InitSysProcs(); + + dprName = ExtractFileName(FileName); + pos = dprName.Pos("."); + if (pos) dprName.SetLength(pos - 1); + + if (BCB) + { + UnitsNum = GetBCBUnits(dprName); + if (!UnitsNum) + { + Screen->Cursor = crDefault; + ShowMessage("Cannot find table of initialization and finalization procedures"); + CleanProject(); + return; + } + } + else + { + if (DelphiVersion == 2) + UnitsNum = GetUnits2(dprName); + else + UnitsNum = GetUnits(dprName); + + if (UnitsNum > 0) + { + ShowUnits(false); + } + } + + if (DelphiVersion <= 2010) + Caption = "Interactive Delphi Reconstructor by crypto: " + SourceFile + " (Delphi-" + String(DelphiVersion) + ")"; + else + Caption = "Interactive Delphi Reconstructor by crypto: " + SourceFile + " (Delphi-XE" + String(DelphiVersion - 2010) + ")"; + + //Show code to allow user make something useful + tsCodeView->Enabled = true; + //ShowCode(EP, 0, -1, -1); + + bEP->Enabled = true; + //Íà âðåìÿ çàãðóçêè ôàéëà îòêëþ÷àåì ïóíêòû ìåíþ + miLoadFile->Enabled = false; + miOpenProject->Enabled = false; + miMRF->Enabled = false; + miSaveProject->Enabled = false; + miSaveDelphiProject->Enabled = false; + lbCXrefs->Enabled = false; + + FProgressBar->Show(); + + AnalyzeThread = new TAnalyzeThread(FMain_11011981, FProgressBar, true); + AnalyzeThread->Resume(); + + WrkDir = ExtractFileDir(FileName); + lbCode->ItemIndex = -1; + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +//Actions after analyzing +void __fastcall TFMain_11011981::AnalyzeThreadDone(TObject* Sender) +{ + if (!AnalyzeThread) return; + + AnalyzeThreadRetVal = AnalyzeThread->GetRetVal(); + if (AnalyzeThread->all && AnalyzeThreadRetVal >= LAST_ANALYZE_STEP) + { + ProjectLoaded = true; + ProjectModified = true; + AddExe2MRF(SourceFile); + } + + FProgressBar->Close(); + //Restore menu items + miLoadFile->Enabled = true; + miOpenProject->Enabled = true; + miMRF->Enabled = true; + miSaveProject->Enabled = true; + miSaveDelphiProject->Enabled = true; + lbCXrefs->Enabled = true; + + miEditFunctionC->Enabled = true; + miEditFunctionI->Enabled = true; + miFuzzyScanKB->Enabled = true; + miSearchItem->Enabled = true; + miName->Enabled = true; + miViewProto->Enabled = true; + bDecompile->Enabled = true; + + miMapGenerator->Enabled = true; + miCommentsGenerator->Enabled = true; + miIDCGenerator->Enabled = true; + miHiewGenerator->Enabled = true; + miLister->Enabled = true; + miKBTypeInfo->Enabled = true; + miCtdPassword->Enabled = IsValidCodeAdr(CtdRegAdr); + miHex2Double->Enabled = true; + + delete AnalyzeThread; + AnalyzeThread = 0; +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::ImportsValid(DWORD ImpRVA, DWORD ImpSize) +{ + if (ImpRVA || ImpSize) + { + DWORD EntryRVA = ImpRVA; + DWORD EndRVA = ImpRVA + ImpSize; + IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; + + while (1) + { + memmove(&ImportDescriptor, (Image + Adr2Pos(EntryRVA + ImageBase)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); + + if (!ImportDescriptor.OriginalFirstThunk && + !ImportDescriptor.TimeDateStamp && + !ImportDescriptor.ForwarderChain && + !ImportDescriptor.Name && + !ImportDescriptor.FirstThunk) break; + + if (!IsValidImageAdr(ImportDescriptor.Name + ImageBase)) return false; + int NameLength = strlen((char*)(Image + Adr2Pos(ImportDescriptor.Name + ImageBase))); + if (NameLength < 0 || NameLength > 256) return false; + if (!IsValidModuleName(NameLength, Adr2Pos(ImportDescriptor.Name + ImageBase))) return false; + + EntryRVA += sizeof(IMAGE_IMPORT_DESCRIPTOR); + if (EntryRVA >= EndRVA) break; + } + } + return true; +} +//--------------------------------------------------------------------------- +int __fastcall TFMain_11011981::LoadImage(FILE* f, int version, bool loadExp, bool loadImp) +{ + int i, n, m, bytes, pos, SectionsNum, ExpNum, NameLength; + DWORD DataEnd, Items; + String moduleName, modName, sEP; + String impFuncName; + IMAGE_DOS_HEADER DosHeader; + IMAGE_NT_HEADERS NTHeaders; + PIMAGE_SECTION_HEADER SectionHeaders; + char segname[9]; + char msg[1024]; + + fseek(f, 0L, SEEK_SET); + //IDD_ERR_NOT_EXECUTABLE + if (fread(&DosHeader, 1, sizeof(IMAGE_DOS_HEADER), f) != sizeof(IMAGE_DOS_HEADER) || + DosHeader.e_magic != IMAGE_DOS_SIGNATURE) + { + ShowMessage("File is not executable"); + return 0; + } + + fseek(f, DosHeader.e_lfanew, SEEK_SET); + //IDD_ERR_NOT_PE_EXECUTABLE + if (fread(&NTHeaders, 1, sizeof(IMAGE_NT_HEADERS), f) != sizeof(IMAGE_NT_HEADERS) || + NTHeaders.Signature != IMAGE_NT_SIGNATURE) + { + ShowMessage("File is not PE-executable"); + return 0; + } + //IDD_ERR_INVALID_PE_EXECUTABLE + if (NTHeaders.FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER) || + NTHeaders.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) + { + ShowMessage("File is invalid 32-bit PE-executable"); + return 0; + } + //IDD_ERR_INVALID_PE_EXECUTABLE + SectionsNum = NTHeaders.FileHeader.NumberOfSections; + if (!SectionsNum) + { + ShowMessage("File is invalid PE-executable"); + return 0; + } + //SizeOfOptionalHeader may be > than sizeof(IMAGE_OPTIONAL_HEADER) + fseek(f, NTHeaders.FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER), SEEK_CUR); + SectionHeaders = new IMAGE_SECTION_HEADER[SectionsNum]; + + if (fread(SectionHeaders, 1, sizeof(IMAGE_SECTION_HEADER)*SectionsNum, f) != + sizeof(IMAGE_SECTION_HEADER)*SectionsNum) + { + ShowMessage("Invalid section headers"); + delete[] SectionHeaders; + return 0; + } + + ImageBase = NTHeaders.OptionalHeader.ImageBase; + ImageSize = NTHeaders.OptionalHeader.SizeOfImage; + EP = NTHeaders.OptionalHeader.AddressOfEntryPoint; + + TotalSize = 0; + DWORD rsrcVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; + DWORD relocVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; + //Fill SegmentList + for (i = 0; i < SectionsNum; i++) + { + PSegmentInfo segInfo = new SegmentInfo; + segInfo->Start = SectionHeaders[i].VirtualAddress + ImageBase; + segInfo->Flags = SectionHeaders[i].Characteristics; + + if (i + 1 < SectionsNum) + segInfo->Size = SectionHeaders[i + 1].VirtualAddress - SectionHeaders[i].VirtualAddress; + else + segInfo->Size = SectionHeaders[i].Misc.VirtualSize; + + if (!SectionHeaders[i].SizeOfRawData)//uninitialized data + { + //segInfo->Size = SectionHeaders[i].Misc.VirtualSize; + segInfo->Flags |= 0x80000; + } + else if (SectionHeaders[i].VirtualAddress == rsrcVA || SectionHeaders[i].VirtualAddress == relocVA) + { + //segInfo->Size = SectionHeaders[i].SizeOfRawData; + segInfo->Flags |= 0x80000; + } + else + { + //segInfo->Size = SectionHeaders[i].SizeOfRawData; + TotalSize += segInfo->Size; + } + memset(segname, 0, 9); + memmove(segname, SectionHeaders[i].Name, 8); + segInfo->Name = String(segname); + SegmentList->Add((void*)segInfo); + } + //DataEnd = TotalSize; + + //Load Image into memory + Image = new BYTE[TotalSize]; + memset((void*)Image, 0, TotalSize); + int num; + BYTE *p = Image; + for (i = 0; i < SectionsNum; i++) + { + if (SectionHeaders[i].VirtualAddress == rsrcVA || SectionHeaders[i].VirtualAddress == relocVA) continue; + BYTE *sp = p; + fseek(f, SectionHeaders[i].PointerToRawData, SEEK_SET); + DWORD Items = SectionHeaders[i].SizeOfRawData; + if (Items) + { + for (n = 0; Items >= MAX_ITEMS; n++) + { + fread(p, 1, MAX_ITEMS, f); + Items -= MAX_ITEMS; + p += MAX_ITEMS; + } + if (Items) + { + fread(p, 1, Items, f); + p += Items; + } + num = p - Image; + if (i + 1 < SectionsNum) + p = sp + (SectionHeaders[i + 1].VirtualAddress - SectionHeaders[i].VirtualAddress); + } + } + + CodeStart = 0; + Code = Image + CodeStart; + CodeBase = ImageBase + SectionHeaders[0].VirtualAddress; + EP = NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase;//temporary assignment to evaluate BCB ini and fin tables + BCB = false; + + if (version != 2) + { + DWORD evalInitTable = EvaluateInitTable(Image, TotalSize, CodeBase); + if (!evalInitTable) + { + ShowMessage("Cannot find initialization table"); + delete[] SectionHeaders; + delete[] Image; + Image = 0; + return 0; + } + + DWORD evalEP = 0; + //Find instruction mov eax,offset InitTable + for (n = 0; n < TotalSize - 5; n++) + { + if (Image[n] == 0xB8 && *((DWORD*)(Image + n + 1)) == evalInitTable) + { + evalEP = n; + break; + } + } + //Scan up until bytes 0x55 (push ebp) and 0x8B,0xEC (mov ebp,esp) + if (evalEP) + { + while (evalEP != 0) + { + if (Image[evalEP] == 0x55 && Image[evalEP + 1] == 0x8B && Image[evalEP + 2] == 0xEC) + break; + evalEP--; + } + } + //Check evalEP + if (evalEP + CodeBase != NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase) + { + sprintf(msg, "Possible invalid EP (NTHeader:%lX, Evaluated:%lX). Input valid EP?", NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase, evalEP + CodeBase); + if (Application->MessageBox(msg, "Confirmation", MB_YESNO) == IDYES) + { + sEP = InputDialogExec("New EP", "EP:", Val2Str0(NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase)); + if (sEP != "") + { + sscanf(sEP.c_str(), "%lX", &EP); + if (!IsValidImageAdr(EP)) + { + delete[] SectionHeaders; + delete[] Image; + Image = 0; + return 0; + } + } + else + { + delete[] SectionHeaders; + delete[] Image; + Image = 0; + return 0; + } + } + else + { + delete[] SectionHeaders; + delete[] Image; + Image = 0; + return 0; + } + } + else + { + EP = NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase; + } + } + //Find DataStart + //DWORD _codeEnd = DataEnd; + //DataStart = CodeStart; + //for (i = 0; i < SectionsNum; i++) + //{ + // if (SectionHeaders[i].VirtualAddress + ImageBase > EP) + // { + // _codeEnd = SectionHeaders[i].VirtualAddress; + // DataStart = SectionHeaders[i].VirtualAddress; + // break; + // } + //} + delete[] SectionHeaders; + + CodeSize = TotalSize;//_codeEnd - SectionHeaders[0].VirtualAddress; + //DataSize = DataEnd - DataStart; + //DataBase = ImageBase + DataStart; + + Flags = new DWORD[TotalSize]; + memset(Flags, cfUndef, sizeof(DWORD) * TotalSize); + Infos = new PInfoRec[TotalSize]; + memset(Infos, 0, sizeof(PInfoRec) * TotalSize); + BSSInfos = new TStringList; + BSSInfos->Sorted = true; + + if (loadExp) + { + //Load Exports + DWORD ExpRVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + //DWORD ExpSize = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; + + if (ExpRVA) + { + IMAGE_EXPORT_DIRECTORY ExportDescriptor; + memmove(&ExportDescriptor, (Image + Adr2Pos(ExpRVA + ImageBase)), sizeof(IMAGE_EXPORT_DIRECTORY)); + ExpNum = ExportDescriptor.NumberOfFunctions; + DWORD ExpFuncNamPos = ExportDescriptor.AddressOfNames; + DWORD ExpFuncAdrPos = ExportDescriptor.AddressOfFunctions; + DWORD ExpFuncOrdPos = ExportDescriptor.AddressOfNameOrdinals; + + for (i = 0; i < ExpNum; i++) + { + PExportNameRec recE = new ExportNameRec; + + DWORD dp = *((DWORD*)(Image + Adr2Pos(ExpFuncNamPos + ImageBase))); + NameLength = strlen((char*)(Image + Adr2Pos(dp + ImageBase))); + recE->name = String((char*)(Image + Adr2Pos(dp + ImageBase)), NameLength); + + WORD dw = *((WORD*)(Image + Adr2Pos(ExpFuncOrdPos + ImageBase))); + recE->address = *((DWORD*)(Image + Adr2Pos(ExpFuncAdrPos + 4*dw + ImageBase))) + ImageBase; + recE->ord = dw + ExportDescriptor.Base; + ExpFuncList->Add((void*)recE); + + ExpFuncNamPos += 4; + ExpFuncOrdPos += 2; + } + ExpFuncList->Sort(ExportsCmpFunction); + } + } + + DWORD ImpRVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + DWORD ImpSize = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; + + if (loadImp && (ImpRVA || ImpSize)) + { + if (!ImportsValid(ImpRVA, ImpSize)) + { + ShowMessage("Imports not valid, will skip!"); + } + else + { + //Load Imports + DWORD EntryRVA; //Next import decriptor RVA + DWORD EndRVA; //End of imports + DWORD ThunkRVA; //RVA of next thunk (from FirstThunk) + DWORD LookupRVA; //RVA of next thunk (from OriginalFirstTunk or FirstThunk) + DWORD ThunkValue; //Value of next thunk (from OriginalFirstTunk or FirstThunk) + WORD Hint; //Ordinal or hint of imported symbol + + IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; + + //DWORD fnProc = 0; + + //First import descriptor + EntryRVA = ImpRVA; + EndRVA = ImpRVA + ImpSize; + + while (1) + { + memmove(&ImportDescriptor, (Image + Adr2Pos(EntryRVA + ImageBase)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); + //All descriptor fields are NULL - end of list, break + if (!ImportDescriptor.OriginalFirstThunk && + !ImportDescriptor.TimeDateStamp && + !ImportDescriptor.ForwarderChain && + !ImportDescriptor.Name && + !ImportDescriptor.FirstThunk) break; + + NameLength = strlen((char*)(Image + Adr2Pos(ImportDescriptor.Name + ImageBase))); + moduleName = String((char*)(Image + Adr2Pos(ImportDescriptor.Name + ImageBase)), NameLength); + + int pos = moduleName.Pos("."); + if (pos) + modName = moduleName.SubString(1, pos - 1); + else + modName = moduleName; + + if (-1 == ImpModuleList->IndexOf(moduleName)) + ImpModuleList->Add(moduleName); + + //HINSTANCE hLib = LoadLibraryEx(moduleName.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); + + //Define the source of import names (OriginalFirstThunk or FirstThunk) + if (ImportDescriptor.OriginalFirstThunk) + LookupRVA = ImportDescriptor.OriginalFirstThunk; + else + LookupRVA = ImportDescriptor.FirstThunk; + + // ThunkRVA get from FirstThunk always + ThunkRVA = ImportDescriptor.FirstThunk; + //Get Imported Functions + while (1) + { + //Names or ordinals get from LookupTable (this table can be inside OriginalFirstThunk or FirstThunk) + ThunkValue = *((DWORD*)(Image + Adr2Pos(LookupRVA + ImageBase))); + if (!ThunkValue) break; + + //fnProc = 0; + PImportNameRec recI = new ImportNameRec; + + if (ThunkValue & 0x80000000) + { + //By ordinal + Hint = (WORD)(ThunkValue & 0xFFFF); + + //if (hLib) fnProc = (DWORD)GetProcAddress(hLib, (char*)Hint); + + //Addresse get from FirstThunk only + //recI->name = modName + "." + String(Hint); + recI->name = String(Hint); + } + else + { + // by name + Hint = *((WORD*)(Image + Adr2Pos(ThunkValue + ImageBase))); + NameLength = lstrlen((char*)(Image + Adr2Pos(ThunkValue + 2 + ImageBase))); + impFuncName = String((char*)(Image + Adr2Pos(ThunkValue + 2 + ImageBase)), NameLength); + + //if (hLib) + //{ + // fnProc = (DWORD)GetProcAddress(hLib, impFuncName.c_str()); + // memmove((void*)(Image + ThunkRVA), (void*)&fnProc, sizeof(DWORD)); + //} + + recI->name = impFuncName; + } + recI->module = modName; + recI->address = ImageBase + ThunkRVA; + ImpFuncList->Add((void*)recI); + // + SetFlag(cfImport, Adr2Pos(recI->address)); + PInfoRec recN = new InfoRec(Adr2Pos(recI->address), ikData); + recN->SetName(impFuncName); + // + ThunkRVA += 4; + LookupRVA += 4; + } + EntryRVA += sizeof(IMAGE_IMPORT_DESCRIPTOR); + if (EntryRVA >= EndRVA) break; + + //if (hLib) + //{ + // FreeLibrary(hLib); + // hLib = NULL; + //} + } + ImpFuncList->Sort(ImportsCmpFunction); + } + } + return 1; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miOpenProjectClick(TObject *Sender) +{ + DoOpenProjectFile(""); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::DoOpenProjectFile(String FileName) +{ + char *buf; + int n, m, num, len, size, pos; + PInfoRec recN; + PUnitRec recU; + PTypeRec recT; + PFIELDINFO fInfo; + + if (ProjectModified) + { + int res = Application->MessageBox("Save active Project?", "Confirmation", MB_YESNOCANCEL); + if (res == IDCANCEL) return; + if (res == IDYES) + { + if (IDPFile == "") IDPFile = ChangeFileExt(SourceFile, ".idp"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "IDP|*.idp"; + SaveDlg->FileName = IDPFile; + + if (SaveDlg->Execute()) SaveProject(SaveDlg->FileName); + } + } + if (FileName == "") + { + OpenDlg->InitialDir = WrkDir; + OpenDlg->FileName = ""; + OpenDlg->Filter = "IDP|*.idp"; + if (OpenDlg->Execute()) FileName = OpenDlg->FileName; + } + if (FileName != "") + { + if (!FileExists(FileName)) + { + ShowMessage("File " + FileName + " not exists"); + return; + } + CloseProject(); + Init(); + WrkDir = ExtractFileDir(FileName); + OpenProject(FileName); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ReadNode(FILE* fIn, TTreeNode* node, char* buf) +//void __fastcall TFMain_11011981::ReadNode(TStream* stream, TTreeNode* node, char* buf) +{ + //Count + int itemsCount; + fread(&itemsCount, sizeof(itemsCount), 1, fIn);//stream->Read(&itemsCount, sizeof(itemsCount)); + + //Text + int len; + fread(&len, sizeof(len), 1, fIn);//stream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//stream->Read(buf, len); + node->Text = String(buf, len); + FProgressBar->pb->StepIt(); + + for (int n = 0; n < itemsCount; n++) + { + TTreeNode* snode = node->Owner->AddChild(node, ""); + ReadNode(fIn, snode, buf);//ReadNode(stream, snode, buf); + } + Application->ProcessMessages(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::OpenProject(String FileName) +{ + bool _useFuzzy = true; + int n, m, k, u, pos, len, num, cnum, evnum, size, infosCnt, bssCnt, _ver; + int topIdxU, itemIdxU, topIdxI, itemIdxI, topIdxC; + String KBFileName; + PInfoRec recN; + + IDPFile = FileName; + + Screen->Cursor = crHourGlass; + FILE* projectFile = fopen(FileName.c_str(), "rb"); + //Read Delphi version and maximum length of buffer + fseek(projectFile, 12, SEEK_SET); + fread(&_ver, sizeof(_ver), 1, projectFile); + + DelphiVersion = _ver & ~(USER_KNOWLEDGEBASE | SOURCE_LIBRARY); + UserKnowledgeBase = false; + SourceIsLibrary = (_ver & SOURCE_LIBRARY); + if (_ver & USER_KNOWLEDGEBASE) + { + ShowMessage("Choose original Knowledge Base"); + OpenDlg->InitialDir = WrkDir; + OpenDlg->FileName = ""; + OpenDlg->Filter = "BIN|*.bin|All files|*.*"; + if (OpenDlg->Execute()) + { + KBFileName = OpenDlg->FileName; + UserKnowledgeBase = true; + } + else + { + ShowMessage("Native Knowledge Base will be used!"); + _useFuzzy = false; + } + } + if (!UserKnowledgeBase) KBFileName = AppDir + "kb" + DelphiVersion + ".bin"; + + MaxBufLen = 0; + fseek(projectFile, -4L, SEEK_END); + fread(&MaxBufLen, sizeof(MaxBufLen), 1, projectFile); + fclose(projectFile); + + if (!KnowledgeBase.Open(KBFileName.c_str())) + { + Screen->Cursor = crDefault; + ShowMessage("Cannot open KnowledgeBase (may be incorrect Version)"); + return; + } + + Caption = "Interactive Delphi Reconstructor by crypto: " + IDPFile + " (D" + DelphiVersion + ")"; + + SetVmtConsts(DelphiVersion); + + //Disable menu items + miLoadFile->Enabled = false; + miOpenProject->Enabled = false; + miMRF->Enabled = false; + miSaveProject->Enabled = false; + miSaveDelphiProject->Enabled = false; + lbCXrefs->Enabled = false; + + Update(); + + char* buf = new BYTE[MaxBufLen]; + FILE* fIn = fopen(IDPFile.c_str(), "rb"); + if (fIn) + { + //TMemoryStream* inStream = new TMemoryStream(); + //inStream->LoadFromFile(IDPFile); + + char magic[12]; + fread(magic, 12, 1, fIn);//inStream->Read(magic, 12); + fread(&_ver, sizeof(_ver), 1, fIn);//inStream->Read(&_ver, sizeof(_ver)); + DelphiVersion = _ver & ~(USER_KNOWLEDGEBASE | SOURCE_LIBRARY); + + fread(&EP, sizeof(EP), 1, fIn);//inStream->Read(&EP, sizeof(EP)); + fread(&ImageBase, sizeof(ImageBase), 1, fIn);//inStream->Read(&ImageBase, sizeof(ImageBase)); + fread(&ImageSize, sizeof(ImageSize), 1, fIn);//inStream->Read(&ImageSize, sizeof(ImageSize)); + fread(&TotalSize, sizeof(TotalSize), 1, fIn);//inStream->Read(&TotalSize, sizeof(TotalSize)); + fread(&CodeBase, sizeof(CodeBase), 1, fIn);//inStream->Read(&CodeBase, sizeof(CodeBase)); + fread(&CodeSize, sizeof(CodeSize), 1, fIn);//inStream->Read(&CodeSize, sizeof(CodeSize)); + fread(&CodeStart, sizeof(CodeStart), 1, fIn);//inStream->Read(&CodeStart, sizeof(CodeStart)); + + fread(&DataBase, sizeof(DataBase), 1, fIn);//inStream->Read(&DataBase, sizeof(DataBase)); + fread(&DataSize, sizeof(DataSize), 1, fIn);//inStream->Read(&DataSize, sizeof(DataSize)); + fread(&DataStart, sizeof(DataStart), 1, fIn);//inStream->Read(&DataStart, sizeof(DataStart)); + + //SegmentList + fread(&num, sizeof(num), 1, fIn);//inStream->Read(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + PSegmentInfo segInfo = new SegmentInfo; + fread(&segInfo->Start, sizeof(segInfo->Start), 1, fIn);//inStream->Read(&segInfo->Start, sizeof(segInfo->Start)); + fread(&segInfo->Size, sizeof(segInfo->Size), 1, fIn);//inStream->Read(&segInfo->Size, sizeof(segInfo->Size)); + fread(&segInfo->Flags, sizeof(segInfo->Flags), 1, fIn);//inStream->Read(&segInfo->Flags, sizeof(segInfo->Flags)); + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + segInfo->Name = String(buf, len); + SegmentList->Add((void*)segInfo); + } + + Image = new BYTE[TotalSize]; + Code = Image + CodeStart; + Data = Image + DataStart; + DWORD Items = TotalSize; + BYTE* pImage = Image; + + while (Items >= MAX_ITEMS) + { + fread(pImage, MAX_ITEMS, 1, fIn);//inStream->Read(pImage, MAX_ITEMS); + pImage += MAX_ITEMS; + Items -= MAX_ITEMS; + } + if (Items) fread(pImage, Items, 1, fIn);//inStream->Read(pImage, Items); + + Flags = new DWORD[TotalSize]; + Items = TotalSize; + DWORD* pFlags = Flags; + + while (Items >= MAX_ITEMS) + { + fread(pFlags, sizeof(DWORD)*MAX_ITEMS, 1, fIn);//inStream->Read(pFlags, sizeof(DWORD)*MAX_ITEMS); + pFlags += MAX_ITEMS; + Items -= MAX_ITEMS; + } + if (Items) fread(pFlags, sizeof(DWORD)*Items, 1, fIn);//inStream->Read(pFlags, sizeof(DWORD)*Items); + + Infos = new PInfoRec[TotalSize]; + memset((void*)Infos, 0, sizeof(PInfoRec)*TotalSize); + + fread(&infosCnt, sizeof(infosCnt), 1, fIn);//inStream->Read(&infosCnt, sizeof(infosCnt)); + BYTE kind; + for (n = 0; n < TotalSize; n++) + { + fread(&pos, sizeof(pos), 1, fIn);//inStream->Read(&pos, sizeof(pos)); + if (pos == -1) break; + fread(&kind, sizeof(kind), 1, fIn);//inStream->Read(&kind, sizeof(kind)); + recN = new InfoRec(pos, kind); + recN->Load(fIn, buf);//recN->Load(inStream, buf); + } + //BSSInfos + BSSInfos = new TStringList; + fread(&bssCnt, sizeof(bssCnt), 1, fIn);//inStream->Read(&bssCnt, sizeof(bssCnt)); + for (n = 0; n < bssCnt; n++) + { + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + String _adr = String(buf, len); + fread(&kind, sizeof(kind), 1, fIn);//inStream->Read(&kind, sizeof(kind)); + recN = new InfoRec(-1, kind); + recN->Load(fIn, buf);//recN->Load(inStream, buf); + BSSInfos->AddObject(_adr, (TObject*)recN); + } + BSSInfos->Sorted = true; + lbCXrefs->Enabled = true; + + //Units + fread(&num, sizeof(num), 1, fIn);//inStream->Read(&num, sizeof(num)); + + UnitsNum = num; + for (n = 0; n < UnitsNum; n++) + { + PUnitRec recU = new UnitRec; + fread(&recU->trivial, sizeof(recU->trivial), 1, fIn);//inStream->Read(&recU->trivial, sizeof(recU->trivial)); + fread(&recU->trivialIni, sizeof(recU->trivialIni), 1, fIn);//inStream->Read(&recU->trivialIni, sizeof(recU->trivialIni)); + fread(&recU->trivialFin, sizeof(recU->trivialFin), 1, fIn);//inStream->Read(&recU->trivialFin, sizeof(recU->trivialFin)); + fread(&recU->kb, sizeof(recU->kb), 1, fIn);//inStream->Read(&recU->kb, sizeof(recU->kb)); + fread(&recU->fromAdr, sizeof(recU->fromAdr), 1, fIn);//inStream->Read(&recU->fromAdr, sizeof(recU->fromAdr)); + fread(&recU->toAdr, sizeof(recU->toAdr), 1, fIn);//inStream->Read(&recU->toAdr, sizeof(recU->toAdr)); + fread(&recU->finadr, sizeof(recU->finadr), 1, fIn);//inStream->Read(&recU->finadr, sizeof(recU->finadr)); + fread(&recU->finSize, sizeof(recU->finSize), 1, fIn);//inStream->Read(&recU->finSize, sizeof(recU->finSize)); + fread(&recU->iniadr, sizeof(recU->iniadr), 1, fIn);//inStream->Read(&recU->iniadr, sizeof(recU->iniadr)); + fread(&recU->iniSize, sizeof(recU->iniSize), 1, fIn);//inStream->Read(&recU->iniSize, sizeof(recU->iniSize)); + recU->matchedPercent = 0.0; + fread(&recU->iniOrder, sizeof(recU->iniOrder), 1, fIn);//inStream->Read(&recU->iniOrder, sizeof(recU->iniOrder)); + recU->names = new TStringList; + int namesNum = 0; + fread(&namesNum, sizeof(namesNum), 1, fIn);//inStream->Read(&namesNum, sizeof(namesNum)); + for (u = 0; u < namesNum; u++) + { + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + SetUnitName(recU, String(buf, len)); + } + Units->Add((void*)recU); + } + UnitSortField = 0; + CurUnitAdr = 0; + topIdxU = 0; itemIdxU = -1; + topIdxI = 0; itemIdxI = -1; + + if (UnitsNum) + { + fread(&UnitSortField, sizeof(UnitSortField), 1, fIn);//inStream->Read(&UnitSortField, sizeof(UnitSortField)); + fread(&CurUnitAdr, sizeof(CurUnitAdr), 1, fIn);//inStream->Read(&CurUnitAdr, sizeof(CurUnitAdr)); + fread(&topIdxU, sizeof(topIdxU), 1, fIn);//inStream->Read(&topIdxU, sizeof(topIdxU)); + fread(&itemIdxU, sizeof(itemIdxU), 1, fIn);//inStream->Read(&itemIdxU, sizeof(itemIdxU)); + //UnitItems + if (CurUnitAdr) + { + fread(&topIdxI, sizeof(topIdxI), 1, fIn);//inStream->Read(&topIdxI, sizeof(topIdxI)); + fread(&itemIdxI, sizeof(itemIdxI), 1, fIn);//inStream->Read(&itemIdxI, sizeof(itemIdxI)); + } + } + + tsUnits->Enabled = true; + switch (UnitSortField) + { + case 0: + miSortUnitsByAdr->Checked = true; + miSortUnitsByOrd->Checked = false; + miSortUnitsByNam->Checked = false; + break; + case 1: + miSortUnitsByAdr->Checked = false; + miSortUnitsByOrd->Checked = true; + miSortUnitsByNam->Checked = false; + break; + case 2: + miSortUnitsByAdr->Checked = false; + miSortUnitsByOrd->Checked = false; + miSortUnitsByNam->Checked = true; + break; + } + ShowUnits(true); + lbUnits->TopIndex = topIdxU; + lbUnits->ItemIndex = itemIdxU; + + ShowUnitItems(GetUnit(CurUnitAdr), topIdxI, itemIdxI); + + miRenameUnit->Enabled = true; + miSearchUnit->Enabled = true; + miSortUnits->Enabled = true; + miCopyList->Enabled = true; + + miEditFunctionC->Enabled = true; + miEditFunctionI->Enabled = true; + miFuzzyScanKB->Enabled = true; + miSearchItem->Enabled = true; + + //Types + fread(&num, sizeof(num), 1, fIn);//inStream->Read(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + PTypeRec recT = new TypeRec; + fread(&recT->kind, sizeof(recT->kind), 1, fIn);//inStream->Read(&recT->kind, sizeof(recT->kind)); + fread(&recT->adr, sizeof(recT->adr), 1, fIn);//inStream->Read(&recT->adr, sizeof(recT->adr)); + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + recT->name = String(buf, len); + OwnTypeList->Add((void*)recT); + } + RTTISortField = 0; + if (num) fread(&RTTISortField, sizeof(RTTISortField), 1, fIn);//inStream->Read(&RTTISortField, sizeof(RTTISortField)); + //UpdateRTTIs + tsRTTIs->Enabled = true; + miSearchRTTI->Enabled = true; + miSortRTTI->Enabled = true; + + switch (RTTISortField) + { + case 0: + miSortRTTIsByAdr->Checked = true; + miSortRTTIsByKnd->Checked = false; + miSortRTTIsByNam->Checked = false; + break; + case 1: + miSortRTTIsByAdr->Checked = false; + miSortRTTIsByKnd->Checked = true; + miSortRTTIsByNam->Checked = false; + break; + case 2: + miSortRTTIsByAdr->Checked = false; + miSortRTTIsByKnd->Checked = false; + miSortRTTIsByNam->Checked = true; + break; + } + ShowRTTIs(); + + //Forms + fread(&num, sizeof(num), 1, fIn);//inStream->Read(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + TDfm* dfm = new TDfm; + //Flags + fread(&dfm->Flags, sizeof(dfm->Flags), 1, fIn);//inStream->Read(&dfm->Flags, sizeof(dfm->Flags)); + //ResName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + dfm->ResName = String(buf, len); + //Name + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + dfm->Name = String(buf, len); + //ClassName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + dfm->ClassName = String(buf, len); + //MemStream + fread(&size, sizeof(size), 1, fIn);//inStream->Read(&size, sizeof(size)); + dfm->MemStream->Size = size; + while (size >= 4096) + { + fread(buf, 4096, 1, fIn);//inStream->Read(buf, 4096); + dfm->MemStream->Write(buf, 4096); + size -= 4096; + } + if (size) + { + fread(buf, size, 1, fIn);//inStream->Read(buf, size); + dfm->MemStream->Write(buf, size); + } + //Events + dfm->Events = new TList; + fread(&evnum, sizeof(evnum), 1, fIn);//inStream->Read(&evnum, sizeof(evnum)); + for (m = 0; m < evnum; m++) + { + PEventInfo eInfo = new EventInfo; + //EventName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + eInfo->EventName = String(buf, len); + //ProcName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + eInfo->ProcName = String(buf, len); + dfm->Events->Add((void*)eInfo); + } + //Components + fread(&cnum, sizeof(cnum), 1, fIn);//inStream->Read(&cnum, sizeof(cnum)); + if (cnum) + { + dfm->Components = new TList; + for (m = 0; m < cnum; m++) + { + PComponentInfo cInfo = new ComponentInfo; + //Inherited + fread(&cInfo->Inherit, sizeof(cInfo->Inherit), 1, fIn);//inStream->Read(&cInfo->Inherit, sizeof(cInfo->Inherit)); + //HasGlyph + fread(&cInfo->HasGlyph, sizeof(cInfo->HasGlyph), 1, fIn);//inStream->Read(&cInfo->HasGlyph, sizeof(cInfo->HasGlyph)); + //Name + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + cInfo->Name = String(buf, len); + //ClassName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + cInfo->ClassName = String(buf, len); + //Events + cInfo->Events = new TList; + fread(&evnum, sizeof(evnum), 1, fIn);//inStream->Read(&evnum, sizeof(evnum)); + for (k = 0; k < evnum; k++) + { + PEventInfo eInfo = new EventInfo; + //EventName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + eInfo->EventName = String(buf, len); + //ProcName + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + eInfo->ProcName = String(buf, len); + cInfo->Events->Add((void*)eInfo); + } + dfm->Components->Add((void*)cInfo); + } + } + ResInfo->FormList->Add((void*)dfm); + } + //UpdateForms + ResInfo->ShowResources(lbForms); + //Aliases + fread(&num, sizeof(num), 1, fIn);//inStream->Read(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + fread(&len, sizeof(len), 1, fIn);//inStream->Read(&len, sizeof(len)); + fread(buf, len, 1, fIn);//inStream->Read(buf, len); + ResInfo->Aliases->Add(String(buf, len)); + } + InitAliases(false); + tsForms->Enabled = (lbForms->Items->Count > 0); + + //CodeHistory + fread(&CodeHistorySize, sizeof(CodeHistorySize), 1, fIn);//inStream->Read(&CodeHistorySize, sizeof(CodeHistorySize)); + fread(&CodeHistoryPtr, sizeof(CodeHistoryPtr), 1, fIn);//inStream->Read(&CodeHistoryPtr, sizeof(CodeHistoryPtr)); + fread(&CodeHistoryMax, sizeof(CodeHistoryMax), 1, fIn);//inStream->Read(&CodeHistoryMax, sizeof(CodeHistoryMax)); + bCodePrev->Enabled = (CodeHistoryPtr >= 0); + bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); + + CodeHistory.Length = CodeHistorySize; + for (n = 0; n < CodeHistorySize; n++) + fread(&CodeHistory[n], sizeof(PROCHISTORYREC), 1, fIn);//inStream->Read(&CodeHistory[n], sizeof(PROCHISTORYREC)); + + fread(&CurProcAdr, sizeof(CurProcAdr), 1, fIn);//inStream->Read(&CurProcAdr, sizeof(CurProcAdr)); + fread(&topIdxC, sizeof(topIdxC), 1, fIn);//inStream->Read(&topIdxC, sizeof(topIdxC)); + + //Important variables + fread(&HInstanceVarAdr, sizeof(HInstanceVarAdr), 1, fIn);//inStream->Read(&HInstanceVarAdr, sizeof(HInstanceVarAdr)); + fread(&LastTls, sizeof(LastTls), 1, fIn);//inStream->Read(&LastTls, sizeof(LastTls)); + + fread(&Reserved, sizeof(Reserved), 1, fIn);//inStream->Read(&Reserved, sizeof(Reserved)); + fread(&LastResStrNo, sizeof(LastResStrNo), 1, fIn);//inStream->Read(&LastResStrNo, sizeof(LastResStrNo)); + + fread(&CtdRegAdr, sizeof(CtdRegAdr), 1, fIn);//inStream->Read(&CtdRegAdr, sizeof(CtdRegAdr)); + + //UpdateVmtList + FillVmtList(); + //UpdateCode + tsCodeView->Enabled = true; + miGoTo->Enabled = true; + miExploreAdr->Enabled = true; + miSwitchFlag->Enabled = cbMultipleSelection->Checked; + bEP->Enabled = true; + DWORD adr = CurProcAdr; + CurProcAdr = 0; + ShowCode(adr, 0, -1, topIdxC); + //UpdateStrings + tsStrings->Enabled = true; + miSearchString->Enabled = true; + ShowStrings(0); + //UpdateNames + tsNames->Enabled = true; + ShowNames(0); + + Update(); + + //Class Viewer + //Total nodes num (for progress bar) + int nodesNum; + fread(&nodesNum, sizeof(nodesNum), 1, fIn);//inStream->Read(&nodesNum, sizeof(nodesNum)); + if (nodesNum) + { + tvClassesFull->Items->BeginUpdate(); + TTreeNode* root = tvClassesFull->Items->Add(0, ""); + ReadNode(fIn, root, buf);//ReadNode(inStream, root, buf); + tvClassesFull->Items->EndUpdate(); + ClassTreeDone = true; + } + //UpdateClassViewer + tsClassView->Enabled = true; + miViewClass->Enabled = true; + miSearchVMT->Enabled = true; + miCollapseAll->Enabled = true; + miEditClass->Enabled = true; + + if (ClassTreeDone) + { + TTreeNode *root = tvClassesFull->Items->Item[0]; + root->Expanded = true; + rgViewerMode->ItemIndex = 0; + rgViewerMode->Enabled = true; + tvClassesFull->BringToFront(); + } + else + { + rgViewerMode->ItemIndex = 1; + rgViewerMode->Enabled = false; + tvClassesShort->BringToFront(); + } + miClassTreeBuilder->Enabled = true; + + //Just cheking + fread(&MaxBufLen, sizeof(MaxBufLen), 1, fIn);//inStream->Read(&MaxBufLen, sizeof(MaxBufLen)); + fclose(fIn); + } + + if (buf) delete[] buf; + //delete inStream; + + ProjectLoaded = true; + ProjectModified = false; + + AddIdp2MRF(FileName); + + //Enable lemu items + miLoadFile->Enabled = true; + miOpenProject->Enabled = true; + miMRF->Enabled = true; + miSaveProject->Enabled = true; + miSaveDelphiProject->Enabled = true; + + miEditFunctionC->Enabled = true; + miEditFunctionI->Enabled = true; + miFuzzyScanKB->Enabled = _useFuzzy; + miSearchItem->Enabled = true; + miName->Enabled = true; + miViewProto->Enabled = true; + bDecompile->Enabled = true; + + miMapGenerator->Enabled = true; + miCommentsGenerator->Enabled = true; + miIDCGenerator->Enabled = true; + miHiewGenerator->Enabled = true; + miLister->Enabled = true; + miKBTypeInfo->Enabled = true; + miCtdPassword->Enabled = IsValidCodeAdr(CtdRegAdr); + miHex2Double->Enabled = true; + + WrkDir = ExtractFileDir(FileName); + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe1Click(TObject *Sender) +{ + LoadFile(miExe1->Caption, miMRF->Items[0]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe2Click(TObject *Sender) +{ + LoadFile(miExe2->Caption, miMRF->Items[1]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe3Click(TObject *Sender) +{ + LoadFile(miExe3->Caption, miMRF->Items[2]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe4Click(TObject *Sender) +{ + LoadFile(miExe4->Caption, miMRF->Items[3]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe5Click(TObject *Sender) +{ + LoadFile(miExe5->Caption, miMRF->Items[4]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe6Click(TObject *Sender) +{ + LoadFile(miExe6->Caption, miMRF->Items[5]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe7Click(TObject *Sender) +{ + LoadFile(miExe7->Caption, miMRF->Items[6]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miExe8Click(TObject *Sender) +{ + LoadFile(miExe8->Caption, miMRF->Items[7]->Tag); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp1Click(TObject *Sender) +{ + LoadFile(miIdp1->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp2Click(TObject *Sender) +{ + LoadFile(miIdp2->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp3Click(TObject *Sender) +{ + LoadFile(miIdp3->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp4Click(TObject *Sender) +{ + LoadFile(miIdp4->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp5Click(TObject *Sender) +{ + LoadFile(miIdp5->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp6Click(TObject *Sender) +{ + LoadFile(miIdp6->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp7Click(TObject *Sender) +{ + LoadFile(miIdp7->Caption, -1); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIdp8Click(TObject *Sender) +{ + LoadFile(miIdp8->Caption, -1); +} +//--------------------------------------------------------------------------- +//SAVE PROJECT +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSaveProjectClick(TObject *Sender) +{ + if (IDPFile == "") IDPFile = ChangeFileExt(SourceFile, ".idp"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "IDP|*.idp"; + SaveDlg->FileName = IDPFile; + + if (SaveDlg->Execute()) SaveProject(SaveDlg->FileName); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::WriteNode(FILE* f, TTreeNode* node) +//void __fastcall TFMain_11011981::WriteNode(TStream* stream, TTreeNode* node) +{ + //Count + int itemsCount = node->Count; + fwrite(&itemsCount, sizeof(itemsCount), 1, f);//stream->Write(&itemsCount, sizeof(itemsCount)); + FProgressBar->pb->StepIt(); + + //Text + int len = node->Text.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, f);//stream->Write(&len, sizeof(len)); + fwrite(node->Text.c_str(), len, 1, f);//stream->Write(node->Text.c_str(), len); + + for (int n = 0; n < itemsCount; n++) + { + WriteNode(f, node->Item[n]);//WriteNode(stream, node->Item[n]); + } + Application->ProcessMessages(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::SaveProject(String FileName) +{ + int n, m, k, len, num, cnum, evnum, size, pos, res, infosCnt, topIdx, itemIdx; + FILE* outF;//TMemoryStream* outStream = 0; + BYTE buf[4096]; + + if (FileExists(FileName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + Screen->Cursor = crHourGlass; + IDPFile = FileName; + + try + { + outF = fopen(IDPFile.c_str(), "wb+");//outStream = new TMemoryStream(); + if (outF) + { + + FProgressBar->Show(); + + char* magic = "IDR proj v.3"; + fwrite(magic, 12, 1, outF);//outStream->Write(magic, 12); + int _ver = DelphiVersion; + if (UserKnowledgeBase) _ver |= USER_KNOWLEDGEBASE; + if (SourceIsLibrary) _ver |= SOURCE_LIBRARY; + fwrite(&_ver, sizeof(_ver), 1, outF);//outStream->Write(&_ver, sizeof(_ver)); + + fwrite(&EP, sizeof(EP), 1, outF);//outStream->Write(&EP, sizeof(EP)); + fwrite(&ImageBase, sizeof(ImageBase), 1, outF);//outStream->Write(&ImageBase, sizeof(ImageBase)); + fwrite(&ImageSize, sizeof(ImageSize), 1, outF);//outStream->Write(&ImageSize, sizeof(ImageSize)); + fwrite(&TotalSize, sizeof(TotalSize), 1, outF);//outStream->Write(&TotalSize, sizeof(TotalSize)); + fwrite(&CodeBase, sizeof(CodeBase), 1, outF);//outStream->Write(&CodeBase, sizeof(CodeBase)); + fwrite(&CodeSize, sizeof(CodeSize), 1, outF);//outStream->Write(&CodeSize, sizeof(CodeSize)); + fwrite(&CodeStart, sizeof(CodeStart), 1, outF);//outStream->Write(&CodeStart, sizeof(CodeStart)); + + fwrite(&DataBase, sizeof(DataBase), 1, outF);//outStream->Write(&DataBase, sizeof(DataBase)); + fwrite(&DataSize, sizeof(DataSize), 1, outF);//outStream->Write(&DataSize, sizeof(DataSize)); + fwrite(&DataStart, sizeof(DataStart), 1, outF);//outStream->Write(&DataStart, sizeof(DataStart)); + //SegmentList + num = SegmentList->Count; + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; + fwrite(&segInfo->Start, sizeof(segInfo->Start), 1, outF);//outStream->Write(&segInfo->Start, sizeof(segInfo->Start)); + fwrite(&segInfo->Size, sizeof(segInfo->Size), 1, outF);//outStream->Write(&segInfo->Size, sizeof(segInfo->Size)); + fwrite(&segInfo->Flags, sizeof(segInfo->Flags), 1, outF);//outStream->Write(&segInfo->Flags, sizeof(segInfo->Flags)); + len = segInfo->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(segInfo->Name.c_str(), len, 1, outF);//outStream->Write(segInfo->Name.c_str(), len); + } + + DWORD Items = TotalSize; + BYTE *pImage = Image; + FProgressBar->StartProgress("Writing Image...", "", (Items + MAX_ITEMS - 1)/MAX_ITEMS); + while (Items >= MAX_ITEMS) + { + FProgressBar->pb->StepIt(); + fwrite(pImage, MAX_ITEMS, 1, outF);//outStream->Write(pImage, MAX_ITEMS); + pImage += MAX_ITEMS; + Items -= MAX_ITEMS; + } + if (Items) fwrite(pImage, Items, 1, outF);//outStream->Write(pImage, Items); + + Items = TotalSize; + DWORD *pFlags = Flags; + FProgressBar->StartProgress("Writing Flags...", "", (Items + MAX_ITEMS - 1)/MAX_ITEMS); + while (Items >= MAX_ITEMS) + { + FProgressBar->pb->StepIt(); + fwrite(pFlags, sizeof(DWORD), MAX_ITEMS, outF);//outStream->Write(pFlags, sizeof(DWORD)*MAX_ITEMS); + pFlags += MAX_ITEMS; + Items -= MAX_ITEMS; + } + if (Items) fwrite(pFlags, sizeof(DWORD), Items, outF);//outStream->Write(pFlags, sizeof(DWORD)*Items); + + infosCnt = 0; + for (n = 0; n < TotalSize; n++) + { + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN) infosCnt++; + } + fwrite(&infosCnt, sizeof(infosCnt), 1, outF);//outStream->Write(&infosCnt, sizeof(infosCnt)); + + FProgressBar->StartProgress("Writing Infos Objects (number = " + String(infosCnt) + ")...", "", TotalSize / 4096); + MaxBufLen = 0; + BYTE kind; + try + { + for (n = 0; n < TotalSize; n++) + { + if ((n & 4095) == 0) + { + FProgressBar->pb->StepIt(); + Application->ProcessMessages(); + } + + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN) + { + //Position + pos = n; + fwrite(&pos, sizeof(pos), 1, outF);//outStream->Write(&pos, sizeof(pos)); + kind = recN->kind; + fwrite(&kind, sizeof(kind), 1, outF);//outStream->Write(&kind, sizeof(kind)); + recN->Save(outF);//recN->Save(outStream); + } + } + } + catch (Exception &exception) + { + ShowMessage("Error at " + Val2Str8(Pos2Adr(n))); + } + //Last position = -1 -> end of items + pos = -1; fwrite(&pos, sizeof(pos), 1, outF);//outStream->Write(&pos, sizeof(pos)); + + //BSSInfos + String _adr; + int bssCnt = BSSInfos->Count; + fwrite(&bssCnt, sizeof(bssCnt), 1, outF);//outStream->Write(&bssCnt, sizeof(bssCnt)); + for (n = 0; n < bssCnt; n++) + { + _adr = BSSInfos->Strings[n]; + len = _adr.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(_adr.c_str(), len, 1, outF);//outStream->Write(_adr.c_str(), len); + PInfoRec recN = (PInfoRec)BSSInfos->Objects[n]; + kind = recN->kind; + fwrite(&kind, sizeof(kind), 1, outF);//outStream->Write(&kind, sizeof(kind)); + recN->Save(outF);//recN->Save(outStream); + } + + //Units + num = UnitsNum; + FProgressBar->StartProgress("Writing Units (number = "+String(num)+")...", "", num); + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + FProgressBar->pb->StepIt(); + Application->ProcessMessages(); + PUnitRec recU = (PUnitRec)Units->Items[n]; + fwrite(&recU->trivial, sizeof(recU->trivial), 1, outF);//outStream->Write(&recU->trivial, sizeof(recU->trivial)); + fwrite(&recU->trivialIni, sizeof(recU->trivialIni), 1, outF);//outStream->Write(&recU->trivialIni, sizeof(recU->trivialIni)); + fwrite(&recU->trivialFin, sizeof(recU->trivialFin), 1, outF);//outStream->Write(&recU->trivialFin, sizeof(recU->trivialFin)); + fwrite(&recU->kb, sizeof(recU->kb), 1, outF);//outStream->Write(&recU->kb, sizeof(recU->kb)); + fwrite(&recU->fromAdr, sizeof(recU->fromAdr), 1, outF);//outStream->Write(&recU->fromAdr, sizeof(recU->fromAdr)); + fwrite(&recU->toAdr, sizeof(recU->toAdr), 1, outF);//outStream->Write(&recU->toAdr, sizeof(recU->toAdr)); + fwrite(&recU->finadr, sizeof(recU->finadr), 1, outF);//outStream->Write(&recU->finadr, sizeof(recU->finadr)); + fwrite(&recU->finSize, sizeof(recU->finSize), 1, outF);//outStream->Write(&recU->finSize, sizeof(recU->finSize)); + fwrite(&recU->iniadr, sizeof(recU->iniadr), 1, outF);//outStream->Write(&recU->iniadr, sizeof(recU->iniadr)); + fwrite(&recU->iniSize, sizeof(recU->iniSize), 1, outF);//outStream->Write(&recU->iniSize, sizeof(recU->iniSize)); + fwrite(&recU->iniOrder, sizeof(recU->iniOrder), 1, outF);//outStream->Write(&recU->iniOrder, sizeof(recU->iniOrder)); + int namesNum = recU->names->Count; + fwrite(&namesNum, sizeof(namesNum), 1, outF);//outStream->Write(&namesNum, sizeof(namesNum)); + for (int u = 0; u < namesNum; u++) + { + len = recU->names->Strings[u].Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(recU->names->Strings[u].c_str(), len, 1, outF);//outStream->Write(recU->names->Strings[u].c_str(), len); + } + } + if (num) + { + fwrite(&UnitSortField, sizeof(UnitSortField), 1, outF);//outStream->Write(&UnitSortField, sizeof(UnitSortField)); + fwrite(&CurUnitAdr, sizeof(CurUnitAdr), 1, outF);//outStream->Write(&CurUnitAdr, sizeof(CurUnitAdr)); + topIdx = lbUnits->TopIndex; + fwrite(&topIdx, sizeof(topIdx), 1, outF);//outStream->Write(&topIdx, sizeof(topIdx)); + itemIdx = lbUnits->ItemIndex; + fwrite(&itemIdx, sizeof(itemIdx), 1, outF);//outStream->Write(&itemIdx, sizeof(itemIdx)); + //UnitItems + if (CurUnitAdr) + { + topIdx = lbUnitItems->TopIndex; + fwrite(&topIdx, sizeof(topIdx), 1, outF);//outStream->Write(&topIdx, sizeof(topIdx)); + itemIdx = lbUnitItems->ItemIndex; + fwrite(&itemIdx, sizeof(itemIdx), 1, outF);//outStream->Write(&itemIdx, sizeof(itemIdx)); + } + } + + //Types + num = OwnTypeList->Count; + FProgressBar->StartProgress("Writing Types (number = "+String(num)+")...", "", num); + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + FProgressBar->pb->StepIt(); + Application->ProcessMessages(); + PTypeRec recT = (PTypeRec)OwnTypeList->Items[n]; + fwrite(&recT->kind, sizeof(recT->kind), 1, outF);//outStream->Write(&recT->kind, sizeof(recT->kind)); + fwrite(&recT->adr, sizeof(recT->adr), 1, outF);//outStream->Write(&recT->adr, sizeof(recT->adr)); + len = recT->name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(recT->name.c_str(), len, 1, outF);//outStream->Write(recT->name.c_str(), len); + } + if (num) fwrite(&RTTISortField, sizeof(RTTISortField), 1, outF);//outStream->Write(&RTTISortField, sizeof(RTTISortField)); + + //Forms + num = ResInfo->FormList->Count; + FProgressBar->StartProgress("Writing Forms (number = "+String(num)+")...", "", num); + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + FProgressBar->pb->StepIt(); + Application->ProcessMessages(); + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + //Flags + fwrite(&dfm->Flags, sizeof(dfm->Flags), 1, outF);//outStream->Write(&dfm->Flags, sizeof(dfm->Flags)); + //ResName + len = dfm->ResName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(dfm->ResName.c_str(), len, 1, outF);//outStream->Write(dfm->ResName.c_str(), len); + //Name + len = dfm->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(dfm->Name.c_str(), len, 1, outF);//outStream->Write(dfm->Name.c_str(), len); + //ClassName + len = dfm->ClassName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(dfm->ClassName.c_str(), len, 1, outF);//outStream->Write(dfm->ClassName.c_str(), len); + //MemStream + size = dfm->MemStream->Size; if (4096 > MaxBufLen) MaxBufLen = 4096; + fwrite(&size, sizeof(size), 1, outF);//outStream->Write(&size, sizeof(size)); + dfm->MemStream->Seek(0, soFromBeginning); + while (size >= 4096) + { + dfm->MemStream->Read(buf, 4096); + fwrite(buf, 4096, 1, outF);//outStream->Write(buf, 4096); + size -= 4096; + } + if (size) + { + dfm->MemStream->Read(buf, size); + fwrite(buf, size, 1, outF);//outStream->Write(buf, size); + } + //Events + evnum = (dfm->Events) ? dfm->Events->Count : 0; + fwrite(&evnum, sizeof(evnum), 1, outF);//outStream->Write(&evnum, sizeof(evnum)); + for (m = 0; m < evnum; m++) + { + PEventInfo eInfo = (PEventInfo)dfm->Events->Items[m]; + //EventName + len = eInfo->EventName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(eInfo->EventName.c_str(), len, 1, outF);//outStream->Write(eInfo->EventName.c_str(), len); + //ProcName + len = eInfo->ProcName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(eInfo->ProcName.c_str(), len, 1, outF);//outStream->Write(eInfo->ProcName.c_str(), len); + } + //Components + cnum = (dfm->Components) ? dfm->Components->Count : 0; + fwrite(&cnum, sizeof(cnum), 1, outF);//outStream->Write(&cnum, sizeof(cnum)); + for (m = 0; m < cnum; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + //Inherited + fwrite(&cInfo->Inherit, sizeof(cInfo->Inherit), 1, outF);//outStream->Write(&cInfo->Inherit, sizeof(cInfo->Inherit)); + //HasGlyph + fwrite(&cInfo->HasGlyph, sizeof(cInfo->HasGlyph), 1, outF);//outStream->Write(&cInfo->HasGlyph, sizeof(cInfo->HasGlyph)); + //Name + len = cInfo->Name.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(cInfo->Name.c_str(), len, 1, outF);//outStream->Write(cInfo->Name.c_str(), len); + //ClassName + len = cInfo->ClassName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(cInfo->ClassName.c_str(), len, 1, outF);//outStream->Write(cInfo->ClassName.c_str(), len); + //Events + evnum = (cInfo->Events) ? cInfo->Events->Count : 0; + fwrite(&evnum, sizeof(evnum), 1, outF);//outStream->Write(&evnum, sizeof(evnum)); + for (k = 0; k < evnum; k++) + { + PEventInfo eInfo = (PEventInfo)cInfo->Events->Items[k]; + //EventName + len = eInfo->EventName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(eInfo->EventName.c_str(), len, 1, outF);//outStream->Write(eInfo->EventName.c_str(), len); + //ProcName + len = eInfo->ProcName.Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(eInfo->ProcName.c_str(), len, 1, outF);//outStream->Write(eInfo->ProcName.c_str(), len); + } + } + } + //Aliases + num = ResInfo->Aliases->Count; + FProgressBar->StartProgress("Writing Aliases (number = "+String(num)+")...", "", num); + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + for (n = 0; n < num; n++) + { + FProgressBar->pb->StepIt(); + Application->ProcessMessages(); + len = ResInfo->Aliases->Strings[n].Length(); if (len > MaxBufLen) MaxBufLen = len; + fwrite(&len, sizeof(len), 1, outF);//outStream->Write(&len, sizeof(len)); + fwrite(ResInfo->Aliases->Strings[n].c_str(), len, 1, outF);//outStream->Write(ResInfo->Aliases->Strings[n].c_str(), len); + } + + //CodeHistory + fwrite(&CodeHistorySize, sizeof(CodeHistorySize), 1, outF);//outStream->Write(&CodeHistorySize, sizeof(CodeHistorySize)); + fwrite(&CodeHistoryPtr, sizeof(CodeHistoryPtr), 1, outF);//outStream->Write(&CodeHistoryPtr, sizeof(CodeHistoryPtr)); + fwrite(&CodeHistoryMax, sizeof(CodeHistoryMax), 1, outF);//outStream->Write(&CodeHistoryMax, sizeof(CodeHistoryMax)); + PROCHISTORYREC phRec; + FProgressBar->StartProgress("Writing Code History Items (number = "+String(CodeHistorySize)+")...", "", CodeHistorySize); + for (n = 0; n < CodeHistorySize; n++) + { + FProgressBar->pb->StepIt(); + Application->ProcessMessages(); + fwrite(&CodeHistory[n], sizeof(PROCHISTORYREC), 1, outF);//outStream->Write(&CodeHistory[n], sizeof(PROCHISTORYREC)); + } + + fwrite(&CurProcAdr, sizeof(CurProcAdr), 1, outF);//outStream->Write(&CurProcAdr, sizeof(CurProcAdr)); + topIdx = lbCode->TopIndex; + fwrite(&topIdx, sizeof(topIdx), 1, outF);//outStream->Write(&topIdx, sizeof(topIdx)); + + //Important variables + fwrite(&HInstanceVarAdr, sizeof(HInstanceVarAdr), 1, outF);//outStream->Write(&HInstanceVarAdr, sizeof(HInstanceVarAdr)); + fwrite(&LastTls, sizeof(LastTls), 1, outF);//outStream->Write(&LastTls, sizeof(LastTls)); + + fwrite(&Reserved, sizeof(Reserved), 1, outF);//outStream->Write(&Reserved, sizeof(Reserved)); + fwrite(&LastResStrNo, sizeof(LastResStrNo), 1, outF);//outStream->Write(&LastResStrNo, sizeof(LastResStrNo)); + + fwrite(&CtdRegAdr, sizeof(CtdRegAdr), 1, outF);//outStream->Write(&CtdRegAdr, sizeof(CtdRegAdr)); + + FProgressBar->Close(); + //Class Viewer + //Total nodes (for progress) + num = 0; if (ClassTreeDone) num = tvClassesFull->Items->Count; + if (num && Application->MessageBox("Save full Tree of Classes?", "Warning", MB_YESNO) == IDYES) + { + FProgressBar->Show(); + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + if (num) + { + FProgressBar->StartProgress("Writing ClassViewer Tree Nodes (number = "+String(num)+")...", "", num); + TTreeNode* root = tvClassesFull->Items->GetFirstNode(); + WriteNode(outF, root);//WriteNode(outStream, root); + } + FProgressBar->Close(); + } + else + { + num = 0; + fwrite(&num, sizeof(num), 1, outF);//outStream->Write(&num, sizeof(num)); + } + //At end write MaxBufLen + fwrite(&MaxBufLen, sizeof(MaxBufLen), 1, outF);//outStream->Write(&MaxBufLen, sizeof(MaxBufLen)); + fclose(outF); + } + //outStream->SaveToFile(IDPFile); + //delete outStream; + + ProjectModified = false; + + AddIdp2MRF(FileName); + } + catch (EFCreateError &E) + { + ShowMessage("Cannot open output file " + IDPFile); + } + + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AddExe2MRF(String FileName) +{ + int n, m; + for (n = 0; n < 8; n++) + { + TMenuItem* item = miMRF->Items[n]; + if (SameText(FileName, item->Caption)) break; + } + if (n == 8) n--; + + for (m = n; m >= 1; m--) + { + miMRF->Items[m]->Caption = miMRF->Items[m - 1]->Caption; + miMRF->Items[m]->Tag = miMRF->Items[m - 1]->Tag; + miMRF->Items[m]->Visible = (miMRF->Items[m]->Caption != ""); + } + miMRF->Items[0]->Caption = FileName; + miMRF->Items[0]->Tag = DelphiVersion; + miMRF->Items[0]->Visible = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::AddIdp2MRF(String FileName) +{ + int n, m; + for (n = 9; n < 17; n++) + { + TMenuItem* item = miMRF->Items[n]; + if (SameText(FileName, item->Caption)) break; + } + if (n == 17) n--; + + for (m = n; m >= 10; m--) + { + miMRF->Items[m]->Caption = miMRF->Items[m - 1]->Caption; + miMRF->Items[m]->Visible = (miMRF->Items[m]->Caption != ""); + } + miMRF->Items[9]->Caption = FileName; + miMRF->Items[9]->Visible = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miKBTypeInfoClick(TObject *Sender) +{ + int idx; + MProcInfo pInfo; + MTypeInfo tInfo; + String typeName, className, propName, sName; + + sName = InputDialogExec("Enter Type Name", "Name:", ""); + if (sName != "") + { + //Procedure + if (KnowledgeBase.GetKBProcInfo(sName, &pInfo, &idx)) + { + FTypeInfo_11011981->memDescription->Clear(); + FTypeInfo_11011981->memDescription->Lines->Add(KnowledgeBase.GetProcPrototype(&pInfo)); + FTypeInfo_11011981->ShowModal(); + return; + } + //Type + if (KnowledgeBase.GetKBTypeInfo(sName, &tInfo)) + { + FTypeInfo_11011981->ShowKbInfo(&tInfo); + return; + } + //Property + className = ExtractClassName(sName); + propName = ExtractProcName(sName); + while (1) + { + if (KnowledgeBase.GetKBPropertyInfo(className, propName, &tInfo)) + { + FTypeInfo_11011981->ShowKbInfo(&tInfo); + return; + } + className = GetParentName(className); + if (className == "") break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormResize(TObject *Sender) +{ + lbCode->Repaint(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::EditFunction(DWORD Adr) +{ + BYTE tag, callKind; + DWORD adr, rootAdr; + int n, m, a, cnt, size, ofs, offset, dotpos; + char *p; + PUnitRec recU; + PInfoRec recN, recN1; + PXrefRec recX; + PVmtListRec recV; + PMethodRec recM; + PARGINFO argInfo; + String line, name, typeDef, item, className, procName; + char buf[1024]; + + //if (Adr == EP) return; + + recU = GetUnit(Adr); + if (!recU) return; + if (Adr == recU->iniadr || Adr == recU->finadr) return; + + recN = GetInfoRec(Adr); + if (recN) + { + FEditFunctionDlg_11011981->Adr = Adr; + + if (FEditFunctionDlg_11011981->ShowModal() == mrOk) + { + //local vars + if (0)//recN->info.procInfo->locals) + { + cnt = FEditFunctionDlg_11011981->lbVars->Count; + recN->procInfo->DeleteLocals(); + for (n = 0; n < cnt; n++) + { + line = FEditFunctionDlg_11011981->lbVars->Items->Strings[n]; + //'-' - deleted line + strcpy(buf, line.c_str()); + p = strtok(buf, " "); + //offset + sscanf(p, "%lX", &offset); + //size + p = strtok(0, " "); + sscanf(p, "%lX", &size); + //name + p = strtok(0, " :"); + if (stricmp(p, "?")) + name = String(p).Trim(); + else + name = ""; + //type + p = strtok(0, " "); + if (stricmp(p, "?")) + typeDef = String(p).Trim(); + else + typeDef = ""; + recN->procInfo->AddLocal(-offset, size, name, typeDef); + } + } + + ClearFlag(cfPass2, Adr2Pos(Adr)); + AnalyzeProc2(Adr, false, false); + AnalyzeArguments(Adr); + + //If virtual then propogate VMT names + //!!! prototype !!! + procName = ExtractProcName(recN->GetName()); + if (recN->procInfo->flags & PF_VIRTUAL) + { + cnt = recN->xrefs->Count; + for (n = 0; n < cnt; n++) + { + recX = (PXrefRec)recN->xrefs->Items[n]; + if (recX->type == 'D') + { + recN1 = GetInfoRec(recX->adr); + ofs = GetMethodOfs(recN1, Adr); + if (ofs != -1) + { + //Down (to root) + adr = recX->adr; rootAdr = adr; + while (adr) + { + recM = GetMethodInfo(adr, 'V', ofs); + if (recM) rootAdr = adr; + adr = GetParentAdr(adr); + } + //Up (all classes that inherits rootAdr) + for (m = 0; m < VmtList->Count; m++) + { + recV = (PVmtListRec)VmtList->Items[m]; + if (IsInheritsByAdr(recV->vmtAdr, rootAdr)) + { + recM = GetMethodInfo(recV->vmtAdr, 'V', ofs); + if (recM) + { + className = GetClsName(recV->vmtAdr); + recM->name = className + "." + procName; + if (recM->address != Adr && !recM->abstract) + { + recN1 = GetInfoRec(recM->address); + if (!recN1->HasName()) + recN1->SetName(className + "." + procName); + else + { + dotpos = recN1->GetName().Pos("."); + recN1->SetName(recN1->GetName().SubString(1, dotpos) + procName); + } + //recN1->name = className + "." + procName; + recN1->kind = recN->kind; + recN1->type = recN->type; + recN1->procInfo->flags |= PF_VIRTUAL; + recN1->procInfo->DeleteArgs(); + recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); + for (a = 1; a < recN->procInfo->args->Count; a++) + { + argInfo = (PARGINFO)recN->procInfo->args->Items[a]; + recN1->procInfo->AddArg(argInfo); + } + } + } + } + } + } + } + } + } + + //DWORD adr = CurProcAdr; + + //Edit current proc + if (Adr == CurProcAdr) + { + RedrawCode(); + //Current proc from current unit + if (recU->fromAdr == CurUnitAdr) + ShowUnitItems(recU, lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + } + else + { + ShowUnitItems(recU, lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + } + ProjectModified = true; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miEditFunctionCClick(TObject *Sender) +{ + EditFunction(CurProcAdr); +} +//--------------------------------------------------------------------------- +//Modified by TerminatorX 30.12.2018 +void __fastcall TFMain_11011981::miMapGeneratorClick(TObject *Sender) +{ + int _posMap; + String procName; + + String mapName = ""; + String SourceFileMap = ""; + if (SourceFile != "") mapName = ChangeFileExt(SourceFile, ".map"); + if (IDPFile != "") mapName = ChangeFileExt(IDPFile, ".map"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "MAP|*.map"; + SaveDlg->FileName = mapName; + + if (!SaveDlg->Execute()) return; + + mapName = SaveDlg->FileName; + if (FileExists(mapName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + Screen->Cursor = crHourGlass; + FILE *fMap = fopen(mapName.c_str(), "wt+"); + if (!fMap) + { + MessageDlg("Cannot open map file", mtWarning, TMsgDlgButtons() << mbOK, 0); + return; + } + SourceFileMap = SourceFile; + _posMap = SourceFileMap.LastDelimiter("\\"); + if (_posMap) SourceFileMap = SourceFileMap.SubString(_posMap + 1, SourceFileMap.Length()); + + fprintf(fMap, "\n Name: %s EP: %08X : Size: %08X\n", SourceFileMap, EP - CodeBase, CodeSize); + fprintf(fMap, "\n Start Length Name Class\n"); + fprintf(fMap, " 0001:00000000 %09XH CODE CODE\n", CodeSize); + fprintf(fMap, "\n\n Address Publics by Value _ RVA+Base\n\n"); + + for (int n = 0; n < CodeSize; n++) + { + if (IsFlagSet(cfProcStart, n) && !IsFlagSet(cfEmbedded, n)) + { + int adr = Pos2Adr(n); + PInfoRec recN = GetInfoRec(adr); + if (recN) + { + if (adr != EP) + { + PUnitRec recU = GetUnit(adr); + if (recU) + { + String moduleName = GetUnitName(recU); + if (adr == recU->iniadr) + procName = "Initialization"; + else if (adr == recU->finadr) + procName = "Finalization"; + else + procName = recN->MakeMapName(adr); + + fprintf(fMap, " 0001:%08X %s.%s_%08X\n", n, moduleName.c_str(), procName.c_str(), adr); + } + else + { + procName = recN->MakeMapName(adr); + fprintf(fMap, " 0001:%08X %s_%08X\n", n, procName.c_str(), adr); + } + } + else + { + fprintf(fMap, " 0001:%08X EntryPoint_%08X\n", n, adr); + } + } + } + } + + fprintf(fMap, "\nProgram entry point at 0001:%08X\n", EP - CodeBase); + fclose(fMap); + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCommentsGeneratorClick(TObject *Sender) +{ + String line; + + String txtName = ""; + if (SourceFile != "") txtName = ChangeFileExt(SourceFile, ".txt"); + if (IDPFile != "") txtName = ChangeFileExt(IDPFile, ".txt"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "TXT|*.txt"; + SaveDlg->FileName = txtName; + + if (!SaveDlg->Execute()) return; + + txtName = SaveDlg->FileName; + + if (FileExists(txtName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + Screen->Cursor = crHourGlass; + + FILE* lstF = fopen(txtName.c_str(), "wt+"); + /* + for (int n = 0; n < CodeSize; n++) + { + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->picode) fprintf(lstF, "C %08lX %s\n", CodeBase + n, MakeComment(recN->picode).c_str()); + } + */ + for (int n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + if (recU->kb || recU->trivial) continue; + + for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + if (adr == recU->finadr) + { + if (!recU->trivialFin) OutputCode(lstF, adr, "", true); + continue; + } + if (adr == recU->iniadr) + { + if (!recU->trivialIni) OutputCode(lstF, adr, "", true); + continue; + } + + int pos = Adr2Pos(adr); + PInfoRec recN = GetInfoRec(adr); + if (!recN) continue; + + BYTE kind = recN->kind; + + if (kind == ikProc || + kind == ikFunc || + kind == ikConstructor || + kind == ikDestructor) + { + OutputCode(lstF, adr, "", true); + continue; + } + + if (IsFlagSet(cfProcStart, pos)) + { + if (recN->kind == ikConstructor) + { + OutputCode(lstF, adr, "", true); + } + else if (recN->kind == ikDestructor) + { + OutputCode(lstF, adr, "", true); + } + else + OutputCode(lstF, adr, "", true); + } + } + } + fclose(lstF); + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miIDCGeneratorClick(TObject *Sender) +{ + String idcName = "", idcTemplate = ""; + if (SourceFile != "") + { + idcName = ChangeFileExt(SourceFile, ".idc"); + idcTemplate = ChangeFileExt(SourceFile, ""); + } + if (IDPFile != "") + { + idcName = ChangeFileExt(IDPFile, ".idc"); + idcTemplate = ChangeFileExt(IDPFile, ""); + } + + TSaveIDCDialog* SaveIDCDialog = new TSaveIDCDialog(this, "SAVEIDCDLG"); + SaveIDCDialog->InitialDir = WrkDir; + SaveIDCDialog->Filter = "IDC|*.idc"; + SaveIDCDialog->FileName = idcName; + + if (!SaveIDCDialog->Execute()) return; + + idcName = SaveIDCDialog->FileName; + delete SaveIDCDialog; + + if (FileExists(idcName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + if (SplitIDC) + { + if (FIdcSplitSize->ShowModal() == mrCancel) return; + } + + Screen->Cursor = crHourGlass; + + FILE* idcF = fopen(idcName.c_str(), "wt+"); + TIDCGen *idcGen = new TIDCGen(idcF, SplitSize); + + idcGen->OutputHeaderFull(); + + int pos, curSize; + + for (pos = 0, curSize = 0; pos < TotalSize; pos++) + { + PInfoRec recN = GetInfoRec(Pos2Adr(pos)); + if (!recN) continue; + + if (SplitIDC && idcGen->CurrentBytes >= SplitSize) + { + fprintf(idcF, "}"); + fclose(idcF); + idcName = idcTemplate + "_" + idcGen->CurrentPartNo + ".idc"; + idcF = fopen(idcName.c_str(), "wt+"); + idcGen->NewIDCPart(idcF); + idcGen->OutputHeaderShort(); + } + + BYTE kind = recN->kind; + BYTE len; + + if (IsFlagSet(cfRTTI, pos)) + { + PUnitRec recU = GetUnit(Pos2Adr(pos)); + if (!recU) continue; + + if (recU->names->Count == 1) + idcGen->unitName = recU->names->Strings[0]; + else + idcGen->unitName = ".Unit" + String(recU->iniOrder); + + switch (kind) + { + case ikInteger: //1 + idcGen->OutputRTTIInteger(kind, pos); + break; + case ikChar: //2 + idcGen->OutputRTTIChar(kind, pos); + break; + case ikEnumeration: //3 + idcGen->OutputRTTIEnumeration(kind, pos, Pos2Adr(pos)); + break; + case ikFloat: //4 + idcGen->OutputRTTIFloat(kind, pos); + break; + case ikString: //5 + idcGen->OutputRTTIString(kind, pos); + break; + case ikSet: //6 + idcGen->OutputRTTISet(kind, pos); + break; + case ikClass: //7 + idcGen->OutputRTTIClass(kind, pos); + break; + case ikMethod: //8 + idcGen->OutputRTTIMethod(kind, pos); + break; + case ikWChar: //9 + idcGen->OutputRTTIWChar(kind, pos); + break; + case ikLString: //0xA + idcGen->OutputRTTILString(kind, pos); + break; + case ikWString: //0xB + idcGen->OutputRTTIWString(kind, pos); + break; + case ikVariant: //0xC + idcGen->OutputRTTIVariant(kind, pos); + break; + case ikArray: //0xD + idcGen->OutputRTTIArray(kind, pos); + break; + case ikRecord: //0xE + idcGen->OutputRTTIRecord(kind, pos); + break; + case ikInterface: //0xF + idcGen->OutputRTTIInterface(kind, pos); + break; + case ikInt64: //0x10 + idcGen->OutputRTTIInt64(kind, pos); + break; + case ikDynArray: //0x11 + idcGen->OutputRTTIDynArray(kind, pos); + break; + case ikUString: //0x12 + idcGen->OutputRTTIUString(kind, pos); + break; + case ikClassRef: //0x13 + idcGen->OutputRTTIClassRef(kind, pos); + break; + case ikPointer: //0x14 + idcGen->OutputRTTIPointer(kind, pos); + break; + case ikProcedure: //0x15 + idcGen->OutputRTTIProcedure(kind, pos); + break; + } + continue; + } + if (kind == ikVMT) + { + idcGen->OutputVMT(pos, recN); + continue; + } + if (kind == ikString) + { + idcGen->MakeShortString(pos); + continue; + } + if (kind == ikLString) + { + idcGen->MakeLString(pos); + continue; + } + if (kind == ikWString) + { + idcGen->MakeWString(pos); + continue; + } + if (kind == ikUString) + { + idcGen->MakeUString(pos); + continue; + } + if (kind == ikCString) + { + idcGen->MakeCString(pos); + continue; + } + if (kind == ikResString) + { + idcGen->OutputResString(pos, recN); + continue; + } + if (kind == ikGUID) + { + idcGen->MakeArray(pos, 16); + continue; + } + if (kind == ikData) + { + idcGen->OutputData(pos, recN); + continue; + } + if (IsFlagSet(cfProcStart, pos)) + { + pos += idcGen->OutputProc(pos, recN, IsFlagSet(cfImport, pos)); + } + } + fprintf(idcF, "}"); + fclose(idcF); + delete idcGen; + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmUnitsPopup(TObject *Sender) +{ + if (lbUnits->ItemIndex < 0) return; + + String item = lbUnits->Items->Strings[lbUnits->ItemIndex]; + DWORD adr; + sscanf(item.c_str() + 1, "%lX", &adr); + PUnitRec recU = GetUnit(adr); + miRenameUnit->Enabled = (!recU->kb && recU->names->Count <= 1); +} +//--------------------------------------------------------------------------- +//MXXXXXXXXM COP Op1, Op2, Op3;commentF +//XXXXXXXX - address +//F - flags (1:cfLoc; 2:cfSkip; 4:cfLoop; 8:jmp or jcc +void __fastcall TFMain_11011981::lbCodeDrawItem(TWinControl *Control, + int Index, TRect &Rect, TOwnerDrawState State) +{ + bool ib; + BYTE _f, _db; + int n, flags, _instrlen, _textLen, _len, _sWid, _cPos, _offset, _ap; + int _dbPos, _ddPos; + DWORD _adr, _val, _dd; + TColor _color; + TListBox *lb; + TCanvas *canvas; + String text, _item, _comment; + PInfoRec _recN; + DISINFO _disInfo; + + //After closing Project we cannot execute this handler (Code = 0) + if (!Image) return; + + lb = (TListBox*)Control; + canvas = lb->Canvas; + + if (Index < lb->Count) + { + flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); + if (!Control->UseRightToLeftAlignment()) + Rect.Left += 2; + else + Rect.Right -= 2; + + text = lb->Items->Strings[Index]; _textLen = text.Length(); + //lb->ItemHeight = canvas->TextHeight("T"); + + //First row (name of procedure with prototype) output without highlighting + if (!Index) + { + Rect.Right = Rect.Left; + DrawOneItem(text, canvas, Rect, 0, flags); + return; + } + //F + _f = text[_textLen]; + canvas->Brush->Color = TColor(0xFFFFFF); + if (State.Contains(odSelected)) + canvas->Brush->Color = TColor(0xFFFFC0); + else if (_f & 2)//skip + canvas->Brush->Color = TColor(0xF5F5FF); + canvas->FillRect(Rect); + + //Width of space + _sWid = canvas->TextWidth(" "); + //Comment position + _cPos = text.Pos(";"); + //Sign for > (blue) + _item = text.SubString(1, 1); + Rect.Right = Rect.Left; + DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); + + //Address (loop is blue, loc is black, others are light gray) + _item = text.SubString(2, 8); _adr = StrToInt(String("$") + _item); + //loop or loc + if (_f & 5) + _color = TColor(0xFF8080); + else + _color = TColor(0xBBBBBB); //LightGray + DrawOneItem(_item, canvas, Rect, _color, flags); + + //Sign for > (blue) + _item = text.SubString(10, 1); + DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); + + //Data (case or exeption table) + _dbPos = text.Pos(" db "); + _ddPos = text.Pos(" dd "); + if (_dbPos || _ddPos) + { + Rect.Right += 7 * _sWid; + if (_dbPos) + { + DrawOneItem("db", canvas, Rect, TColor(0), flags); + //Spaces after db + Rect.Right += (ASMMAXCOPLEN - 2) * _sWid; + _db = *(Code + Adr2Pos(_adr)); + DrawOneItem(Val2Str0((DWORD)_db), canvas, Rect, TColor(0xFF8080), flags); + } + else if (_ddPos) + { + DrawOneItem("dd", canvas, Rect, TColor(0), flags); + //Spaces after dd + Rect.Right += (ASMMAXCOPLEN - 2) * _sWid; + _dd = *((DWORD*)(Code + Adr2Pos(_adr))); + DrawOneItem(Val2Str8(_dd), canvas, Rect, TColor(0xFF8080), flags); + } + //Comment (light gray) + if (_cPos) + { + _item = text.SubString(_cPos, _textLen); + _item.SetLength(_item.Length() - 1); + DrawOneItem(_item, canvas, Rect, TColor(0xBBBBBB), flags); + } + return; + } + //Get instruction tokens + Disasm.Disassemble(Code + Adr2Pos(_adr), (__int64)_adr, &_disInfo, 0); + //repprefix + _len = 0; + if (_disInfo.RepPrefix != -1) + { + _item = RepPrefixTab[_disInfo.RepPrefix]; + _len = _item.Length(); + } + Rect.Right += (6 - _len) * _sWid; + if (_disInfo.RepPrefix != -1) + { + DrawOneItem(_item, canvas, Rect, TColor(0), flags); + } + Rect.Right += _sWid; + + //Cop (black, if float then green) + _item = String(_disInfo.Mnem); _len = _item.Length(); + if (!_disInfo.Float) + _color = TColor(0); + else + _color = TColor(0x808000); + if (!SameText(_item, "movs")) + { + DrawOneItem(_item, canvas, Rect, _color, flags); + //Operands + if (_disInfo.OpNum) + { + Rect.Right += (ASMMAXCOPLEN - _len) * _sWid; + for (n = 0; n < _disInfo.OpNum; n++) + { + if (n) DrawOneItem(",", canvas, Rect, TColor(0), flags); + + ib = (_disInfo.BaseReg != -1 || _disInfo.IndxReg != -1); + _offset = _disInfo.Offset; + //Op1 + if (_disInfo.OpType[n] == otIMM) + { + _val = _disInfo.Immediate; + _ap = Adr2Pos(_val); + _color = TColor(0xFF8080); + if (_ap >= 0 && (_disInfo.Call || _disInfo.Branch)) + { + _recN = GetInfoRec(_val); + if (_recN && _recN->HasName()) + { + _item = _recN->GetName(); + _color = TColor(0xC08000); + } + else + _item = Val2Str8(_val); + } + else + { + if (_val <= 9) + _item = String(_val); + else + { + _item = Val2Str0(_val); + if (!isdigit(_item[1])) _item = "0" + _item; + } + } + DrawOneItem(_item, canvas, Rect, _color, flags); + } + else if (_disInfo.OpType[n] == otREG || _disInfo.OpType[n] == otFST) + { + _item = GetAsmRegisterName(_disInfo.OpRegIdx[n]); + DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); + } + else if (_disInfo.OpType[n] == otMEM) + { + if (_disInfo.OpSize) + { + _item = String(_disInfo.sSize) + " ptr "; + DrawOneItem(_item, canvas, Rect, TColor(0), flags); + } + if (_disInfo.SegPrefix != -1) + { + _item = String(SegRegTab[_disInfo.SegPrefix]); + DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); + DrawOneItem(":", canvas, Rect, TColor(0), flags); + } + DrawOneItem("[", canvas, Rect, TColor(0), flags); + if (ib) + { + if (_disInfo.BaseReg != -1) + { + _item = GetAsmRegisterName(_disInfo.BaseReg); + DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); + } + if (_disInfo.IndxReg != -1) + { + if (_disInfo.BaseReg != -1) + { + DrawOneItem("+", canvas, Rect, TColor(0), flags); + } + _item = GetAsmRegisterName(_disInfo.IndxReg); + DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); + if (_disInfo.Scale != 1) + { + DrawOneItem("*", canvas, Rect, TColor(0), flags); + _item = String(_disInfo.Scale); + DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); + } + } + if (_offset) + { + if (_offset < 0) + { + _item = "-"; + _offset = -_offset; + } + else + { + _item = "+"; + } + DrawOneItem(_item, canvas, Rect, TColor(0), flags); + if (_offset < 9) + _item = String(_offset); + else + { + _item = Val2Str0(_offset); + if (!isdigit(_item[1])) _item = "0" + _item; + } + DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); + } + } + else + { + if (_offset < 0) _offset = -_offset; + if (_offset < 9) + _item = String(_offset); + else + { + _item = Val2Str0(_offset); + if (!isdigit(_item[1])) _item = "0" + _item; + } + DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); + } + DrawOneItem("]", canvas, Rect, TColor(0), flags); + } + } + } + } + //movsX + else + { + _item += String(_disInfo.sSize[0]); + DrawOneItem(_item, canvas, Rect, _color, flags); + } + //Comment (light gray) + if (_cPos) + { + _item = text.SubString(_cPos, _textLen); + _item.SetLength(_item.Length() - 1); + DrawOneItem(_item, canvas, Rect, TColor(0xBBBBBB), flags); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miListerClick(TObject *Sender) +{ + bool imp, emb; + String line; + + String lstName = ""; + if (SourceFile != "") lstName = ChangeFileExt(SourceFile, ".lst"); + if (IDPFile != "") lstName = ChangeFileExt(IDPFile, ".lst"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "LST|*.lst"; + SaveDlg->FileName = lstName; + + if (!SaveDlg->Execute()) return; + + lstName = SaveDlg->FileName; + + if (FileExists(lstName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + Screen->Cursor = crHourGlass; + + FILE* lstF = fopen(lstName.c_str(), "wt+"); + for (int n = 0; n < UnitsNum; n++) + { + PUnitRec recU = (PUnitRec)Units->Items[n]; + if (recU->kb || recU->trivial) continue; + fprintf(lstF, "//===========================================================================\n"); + fprintf(lstF, "//Unit%03d", recU->iniOrder); + if (recU->names->Count) fprintf(lstF, " (%s)", recU->names->Strings[0]); + fprintf(lstF, "\n"); + + for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + if (adr == recU->finadr) + { + if (!recU->trivialFin) + { + OutputCode(lstF, adr, "procedure Finalization;", false); + } + continue; + } + if (adr == recU->iniadr) + { + if (!recU->trivialIni) + { + OutputCode(lstF, adr, "procedure Initialization;", false); + } + continue; + } + + int pos = Adr2Pos(adr); + PInfoRec recN = GetInfoRec(adr); + if (!recN) continue; + + imp = emb = false; + BYTE kind = recN->kind; + if (IsFlagSet(cfProcStart, pos)) + { + imp = IsFlagSet(cfImport, pos); + emb = (recN->procInfo->flags & PF_EMBED); + } + + if (kind == ikUnknown) continue; + + if (kind > ikUnknown && kind <= ikProcedure && recN->HasName()) + { + if (kind == ikEnumeration || kind == ikSet) + { + line = FTypeInfo_11011981->GetRTTI(adr); + fprintf(lstF, "%s = %s;\n", recN->GetName(), line); + } + else + fprintf(lstF, "%08lX <%s> %s\n", adr, TypeKind2Name(kind), recN->GetName()); + continue; + } + + if (kind == ikResString) + { + fprintf(lstF, "%08lX %s=%s\n", adr, recN->GetName(), recN->rsInfo->value); + continue; + } + + if (kind == ikVMT) + { + fprintf(lstF, "%08lX %s\n", adr, recN->GetName()); + continue; + } + + if (kind == ikGUID) + { + fprintf(lstF, "%08lX %s\n", adr, Guid2String(Code + pos)); + continue; + } + + if (kind == ikConstructor) + { + OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); + continue; + } + + if (kind == ikDestructor) + { + OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); + continue; + } + + if (kind == ikProc) + { + line = ""; + if (imp) + line += "import "; + else if (emb) + line += "embedded "; + line += recN->MakePrototype(adr, true, false, false, true, false); + OutputCode(lstF, adr, line, false); + continue; + } + + if (kind == ikFunc) + { + line = ""; + if (imp) + line += "import "; + else if (emb) + line += "embedded "; + line += recN->MakePrototype(adr, true, false, false, true, false); + OutputCode(lstF, adr, line, false); + continue; + } + + if (IsFlagSet(cfProcStart, pos)) + { + if (kind == ikDestructor) + { + OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); + } + else if (kind == ikDestructor) + { + OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); + } + else + { + line = ""; + if (emb) line += "embedded "; + line += recN->MakePrototype(adr, true, false, false, true, false); + OutputCode(lstF, adr, line, false); + } + } + } + } + fclose(lstF); + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::OutputLine(FILE* OutF, BYTE flags, DWORD Adr, String Content) +{ + //Ouput comments + if (flags & 0x10) + { + char *p = strchr(Content.c_str(), ';'); + if (p) fprintf(OutF, "C %08lX %s\n", Adr, p + 1); + return; + } + + //Jump direction + if (flags & 4) + fprintf(OutF, "<"); + else if (flags & 8) + fprintf(OutF, ">"); + else + fprintf(OutF, " "); + /* + if (flags & 1) + fprintf(OutF, "%08lX\n", Adr); + else + fprintf(OutF, " "); + */ + fprintf(OutF, "%08lX %s\n", Adr, Content.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::OutputCode(FILE* outF, DWORD fromAdr, String prototype, bool onlyComments) +{ + BYTE op, flags; + int row = 0, num, instrLen, instrLen1, instrLen2; + DWORD Adr, Adr1, Pos, lastMovAdr = 0; + int fromPos, curPos, _procSize, _ap, _pos, _idx; + DWORD curAdr; + DWORD lastAdr = 0; + PInfoRec recN, recN1; + String line; + DISINFO DisInfo, DisInfo1; + char disLine[100]; + + fromPos = Adr2Pos(fromAdr); + if (fromPos < 0) return; + + recN = GetInfoRec(fromAdr); + int outRows = MAX_DISASSEMBLE; + if (IsFlagSet(cfImport, fromPos)) outRows = 1; + + if (!onlyComments && prototype != "") + { + fprintf(outF, "//---------------------------------------------------------------------------\n"); + fprintf(outF, "//%s\n", prototype); + } + _procSize = GetProcSize(fromAdr); + curPos = fromPos; curAdr = fromAdr; + + while (row < outRows) + { + //End of procedure + if (curAdr != fromAdr && _procSize && curAdr - fromAdr >= _procSize) break; + flags = 0; + //Only comments? + if (onlyComments) flags |= 0x10; + //Loc? + if (IsFlagSet(cfLoc, curPos)) flags |= 1; + //Skip? + if (IsFlagSet(cfSkip | cfDSkip, curPos)) flags |= 2; + + //If exception table, output it + if (IsFlagSet(cfETable, curPos)) + { + //dd num + num = *((int*)(Code + curPos)); + OutputLine(outF, flags, curAdr, "dd " + String(num)); row++; + curPos += 4; curAdr += 4; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Adr = *((DWORD*)(Code + curPos)); + line = "dd " + Val2Str8(Adr); + //Name of Exception + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN && recN->HasName()) line += ";" + recN->GetName(); + } + OutputLine(outF, flags, curAdr, line); row++; + + //dd offset ExceptionProc + curPos += 4; curAdr += 4; + Adr = *((DWORD*)(Code + curPos)); + OutputLine(outF, flags, curAdr, "dd " + Val2Str8(Adr)); row++; + + curPos += 4; curAdr += 4; + } + continue; + } + + BYTE b1 = Code[curPos]; + BYTE b2 = Code[curPos + 1]; + + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, disLine); + if (!instrLen) + { + OutputLine(outF, flags, curAdr, "???"); row++; + curPos++; curAdr++; + continue; + } + op = Disasm.GetOp(DisInfo.Mnem); + + //Check inside instruction Fixup or ThreadVar + bool NameInside = false; DWORD NameInsideAdr; + for (int k = 1; k < instrLen; k++) + { + if (Infos[curPos + k]) + { + NameInside = true; + NameInsideAdr= curAdr + k; + break; + } + } + + line = String(disLine); + + if (curAdr >= lastAdr) lastAdr = 0; + + //Proc end + if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) + { + OutputLine(outF, flags, curAdr, line); row++; + break; + } + + if (op == OP_MOV) lastMovAdr = DisInfo.Offset; + + if (b1 == 0xEB || //short relative abs jmp or cond jmp + (b1 >= 0x70 && b1 <= 0x7F) || + (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + if (op == OP_JMP) + { + _ap = Adr2Pos(Adr); + recN = GetInfoRec(Adr); + if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) + { + line = "jmp " + recN->GetName(); + } + } + flags |= 8; + if (Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + OutputLine(outF, flags, curAdr, line); row++; + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (b1 == 0xE9) //relative abs jmp or cond jmp + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + _ap = Adr2Pos(Adr); + recN = GetInfoRec(Adr); + if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) + { + line = "jmp " + recN->GetName(); + } + flags |= 8; + if (!recN && Adr >= fromAdr && Adr > lastAdr) lastAdr = Adr; + } + OutputLine(outF, flags, curAdr, line); row++; + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (DisInfo.Call) //call sub_XXXXXXXX + { + Adr = DisInfo.Immediate; + if (IsValidCodeAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN && recN->HasName()) + { + line = "call " + recN->GetName(); + //Found @Halt0 - exit + if (recN->SameName("@Halt0") && fromAdr == EP && !lastAdr) + { + OutputLine(outF, flags, curAdr, line); row++; + break; + } + } + } + recN = GetInfoRec(curAdr); + if (recN && recN->picode) line += ";" + MakeComment(recN->picode); + OutputLine(outF, flags, curAdr, line); row++; + curPos += instrLen; curAdr += instrLen; + continue; + } + + if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) //near absolute indirect jmp (Case) + { + OutputLine(outF, flags, curAdr, line); row++; + if (!IsValidCodeAdr(DisInfo.Offset)) break; + /* + //First instruction + if (curAdr == fromAdr) break; + */ + DWORD cTblAdr = 0, jTblAdr = 0; + + Pos = curPos + instrLen; + Adr = curAdr + instrLen; + //Table address - last 4 bytes of instruction + jTblAdr = *((DWORD*)(Code + Pos - 4)); + //Analyze address range to find table cTbl + if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) cTblAdr = lastMovAdr; + //If exist cTblAdr, skip this table + BYTE CTab[256]; + if (cTblAdr) + { + int CNum = jTblAdr - cTblAdr; + for (int k = 0; k < CNum; k++) + { + BYTE db = Code[Pos]; + CTab[k] = db; + OutputLine(outF, flags, curAdr, "db " + String(db)); row++; + Pos++; Adr++; + } + } + //Check transitions by negative register values (in Delphi 2009) + //bool neg = false; + //Adr1 = *((DWORD*)(Code + Pos - 4)); + //if (IsValidCodeAdr(Adr1) && IsFlagSet(cfLoc, Adr2Pos(Adr1))) neg = true; + + for (int k = 0; k < 4096; k++) + { + //Loc - end of table + if (IsFlagSet(cfLoc, Pos)) break; + + Adr1 = *((DWORD*)(Code + Pos)); + //Validate Adr1 + if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) break; + + //Add row to assembler listing + OutputLine(outF, flags, curAdr, "dd " + Val2Str8(Adr1)); row++; + //Set cfLoc + SetFlag(cfLoc, Adr2Pos(Adr1)); + + Pos += 4; Adr += 4; + if (Adr1 > lastAdr) lastAdr = Adr1; + } + if (Adr > lastAdr) lastAdr = Adr; + curPos = Pos; curAdr = Adr; + continue; + } +//---------------------------------- +//PosTry: xor reg, reg +// push ebp +// push offset @1 +// push fs:[reg] +// mov fs:[reg], esp +// ... +//@2: ... +//At @1 various variants: +//---------------------------------- +//@1: jmp @HandleFinally +// jmp @2 +//---------------------------------- +//@1: jmp @HandleAnyException +// call DoneExcept +//---------------------------------- +//@1: jmp HandleOnException +// dd num +//Äàëåå òàáëèöà èç num çàïèñåé âèäà +// dd offset ExceptionInfo +// dd offset ExceptionProc +//---------------------------------- + if (b1 == 0x68) //try block (push loc_TryBeg) + { + DWORD NPos = curPos + instrLen; + //check that next instruction is push fs:[reg] or retn + if ((Code[NPos] == 0x64 && + Code[NPos + 1] == 0xFF && + ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || + Code[NPos] == 0xC3) + { + Adr = DisInfo.Immediate; //Adr=@1 + if (IsValidCodeAdr(Adr)) + { + if (Adr > lastAdr) lastAdr = Adr; + Pos = Adr2Pos(Adr); + if (Pos >= 0) + { + if (Code[Pos] == 0xE9) //jmp Handle... + { + //Disassemble jmp + instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + + recN = GetInfoRec(DisInfo.Immediate); + if (recN) + { + if (recN->SameName("@HandleFinally")) + { + //jmp HandleFinally + Pos += instrLen1; Adr += instrLen1; + //jmp @2 + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + /* + //@2 + Adr1 = DisInfo.Immediate - 4; + Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); + if (IsValidCodeAdr(Adr) && Adr > lastAdr) lastAdr = Adr; + */ + } + else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) + { + //jmp HandleAnyException + Pos += instrLen1; Adr += instrLen1; + //call DoneExcept + instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); + Adr += instrLen2; + if (Adr > lastAdr) lastAdr = Adr; + } + else if (recN->SameName("@HandleOnException")) + { + //jmp HandleOnException + Pos += instrLen1; Adr += instrLen1; + //Set flag cfETable to correct output data + SetFlag(cfETable, Pos); + //dd num + num = *((int*)(Code + Pos)); Pos += 4; + if (Adr + 4 + 8 * num > lastAdr) lastAdr = Adr + 4 + 8 * num; + + for (int k = 0; k < num; k++) + { + //dd offset ExceptionInfo + Pos += 4; + //dd offset ExceptionProc + Pos += 4; + } + } + } + } + } + } + OutputLine(outF, flags, curAdr, line); row++; + curPos += instrLen; curAdr += instrLen; + continue; + } + } + + //Name inside instruction (Fixip, ThreadVar) + String namei = "", comment = "", name, pname, type, ptype; + if (NameInside) + { + recN = GetInfoRec(NameInsideAdr); + if (recN && recN->HasName()) + { + namei += recN->GetName(); + if (recN->type != "") namei += ":" + recN->type; + } + } + //comment + recN = GetInfoRec(curAdr); + if (recN && recN->picode) comment = MakeComment(recN->picode); + + DWORD targetAdr = 0; + if (IsValidImageAdr(DisInfo.Immediate)) + { + if (!IsValidImageAdr(DisInfo.Offset)) targetAdr = DisInfo.Immediate; + } + else if (IsValidImageAdr(DisInfo.Offset)) + targetAdr = DisInfo.Offset; + + if (targetAdr) + { + name = pname = type = ptype = ""; + _pos = Adr2Pos(targetAdr); + if (_pos >= 0) + { + recN = GetInfoRec(targetAdr); + if (recN) + { + if (recN->kind == ikResString) + { + name = recN->GetName() + ":PResStringRec"; + } + else + { + if (recN->HasName()) + { + name = recN->GetName(); + if (recN->type != "") type = recN->type; + } + else if (IsFlagSet(cfProcStart, _pos)) + name = GetDefaultProcName(targetAdr); + } + } + //For Delphi2 pointers to VMT are distinct + else if (DelphiVersion == 2) + { + recN = GetInfoRec(targetAdr + cVmtSelfPtr); + if (recN && recN->kind == ikVMT && recN->HasName()) + { + name = recN->GetName(); + } + } + Adr = *((DWORD*)(Code + _pos)); + if (IsValidImageAdr(Adr)) + { + recN = GetInfoRec(Adr); + if (recN) + { + if (recN->HasName()) + { + pname = recN->GetName(); + ptype = recN->type; + } + else if (IsFlagSet(cfProcStart, _pos)) + pname = GetDefaultProcName(Adr); + } + } + } + else + { + _idx = BSSInfos->IndexOf(Val2Str8(targetAdr)); + if (_idx != -1) + { + recN = (PInfoRec)BSSInfos->Objects[_idx]; + name = recN->GetName(); + type = recN->type; + } + } + } + if (SameText(comment, name)) name = ""; + if (pname != "") + { + if (comment != "") comment += " "; + comment += "^" + pname; + if (ptype != "") comment += ":" + ptype; + } + else if (name != "") + { + if (comment != "") comment += " "; + comment += name; + if (type != "") comment += ":" + type; + } + + if (comment != "" || namei != "") + { + line += ";"; + if (comment != "") line += comment; + if (namei != "") line += "{" + namei + "}"; + } + if (line.Length() > MAXLEN) line = line.SubString(1, MAXLEN) + "..."; + OutputLine(outF, flags, curAdr, line); row++; + curPos += instrLen; curAdr += instrLen; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::wm_dropFiles(TWMDropFiles& msg) +{ + TFileDropper* fc = new TFileDropper((HDROP)msg.Drop); + try + { + for (int i = 0; i < fc->FileCount; ++i) + { + String droppedFile = fc->Files[i]; + String ext = ExtractFileExt(droppedFile).LowerCase(); + + if (SameText(ext, ".lnk")) + DoOpenDelphiFile(DELHPI_VERSION_AUTO, GetFilenameFromLink(droppedFile), true, true); + else if (SameText(ext, ".idp") && miOpenProject->Enabled) + DoOpenProjectFile(droppedFile); + else if ((SameText(ext, ".exe") || SameText(ext, ".bpl") || SameText(ext, ".dll") || SameText(ext, ".scr")) && miLoadFile->Enabled) + DoOpenDelphiFile(DELHPI_VERSION_AUTO, droppedFile, true, true); + + //Processed the first - and go out - we cannot process more than one file yet + break; + } + //TPoint ptDrop = fc->DropPoint; + } + catch (...) + { + } + delete fc; + msg.Result = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miAboutClick(TObject *Sender) +{ + FAboutDlg_11011981->ShowModal(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miHelpClick(TObject *Sender) +{ + ShellExecute(Handle, "open", Application->HelpFile.c_str(), 0, 0, 1); +} +//--------------------------------------------------------------------------- +#include "TabUnits.cpp" +#include "TabRTTIs.cpp" +#include "TabStrings.cpp" +#include "TabNames.cpp" +#include "CXrefs.cpp" +#include "Analyze1.cpp" +#include "Analyze2.cpp" +#include "AnalyzeArguments.cpp" +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::FormCloseQuery(TObject *Sender, bool &CanClose) +{ + int _res; + + if (AnalyzeThread) + { + AnalyzeThread->Suspend(); + String sbtext0 = FProgressBar->sb->Panels->Items[0]->Text; + String sbtext1 = FProgressBar->sb->Panels->Items[1]->Text; + FProgressBar->Visible = false; + + _res = Application->MessageBox("Analysis is not yet completed. Do You really want to exit IDR?", "Confirmation", MB_YESNO); + if (_res == IDNO) + { + FProgressBar->Visible = true; + FProgressBar->sb->Panels->Items[0]->Text = sbtext0; + FProgressBar->sb->Panels->Items[1]->Text = sbtext1; + FProgressBar->Update(); + + AnalyzeThread->Resume(); + CanClose = false; + return; + } + AnalyzeThread->Terminate(); + } + + if (ProjectLoaded && ProjectModified) + { + _res = Application->MessageBox("Save active Project?", "Confirmation", MB_YESNOCANCEL); + if (_res == IDCANCEL) + { + CanClose = false; + return; + } + if (_res == IDYES) + { + if (IDPFile == "") IDPFile = ChangeFileExt(SourceFile, ".idp"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "IDP|*.idp"; + SaveDlg->FileName = IDPFile; + + if (!SaveDlg->Execute()) + { + CanClose = false; + return; + } + SaveProject(SaveDlg->FileName); + } + CloseProject(); + } + + IniFileWrite(); + + CanClose = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCtdPasswordClick(TObject *Sender) +{ + BYTE op; + DWORD curPos, curAdr; + int instrLen, pwdlen = 0, beg; + String pwds = ""; + BYTE pwd[256]; + DISINFO DisInfo; + + PInfoRec recN = GetInfoRec(CtdRegAdr); + if (recN->xrefs->Count != 1) return; + PXrefRec recX = (PXrefRec)recN->xrefs->Items[0]; + + int ofs; + for (ofs = recX->offset; ofs >= 0; ofs--) + { + if (IsFlagSet(cfPush, Adr2Pos(recX->adr) + ofs)) break; + } + /* + curPos = Adr2Pos(recX->adr) + ofs; + curAdr = Pos2Adr(curPos); + //pwdlen + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo); + pwdlen = DisInfo.Immediate + 1; + curPos += instrLen; curAdr += instrLen; + //pwd + beg = 128; + for (int n = 0; n < pwdlen;) + { + instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo); + op = Disasm.GetOp(DisInfo.Mnem); + //mov [ebp-Ofs], B + if (op == OP_MOV && DisInfo.Op1Type == otMEM && DisInfo.Op2Type == otIMM && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) + { + ofs = DisInfo.Offset; if (128 + ofs < beg) beg = 128 + ofs; + pwd[128 + ofs] = DisInfo.Immediate; + n++; + } + curPos += instrLen; curAdr += instrLen; + } + for (int n = beg; n < beg + pwdlen; n++) + { + pwds += Val2Str2(pwd[n]); + } + */ + PROCHISTORYREC rec; + + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(recX->adr, recX->adr + ofs, -1, -1); + CodeHistoryPush(&rec); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmCodePanelPopup(TObject *Sender) +{ + miEmptyHistory->Enabled = (CodeHistoryPtr > 0); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miEmptyHistoryClick(TObject *Sender) +{ + memmove(&CodeHistory[0], &CodeHistory[CodeHistoryPtr], sizeof(PROCHISTORYREC)); + CodeHistoryPtr = 0; + CodeHistoryMax = CodeHistoryPtr; +} +//--------------------------------------------------------------------------- +PFIELDINFO __fastcall TFMain_11011981::GetField(String TypeName, int Offset, bool* vmt, DWORD* vmtAdr, String prefix) +{ + int n, idx, kind, size, Ofs, Ofs1, Ofs2, pos1, pos2; + DWORD classAdr; + BYTE *p, *ps; + WORD *uses, Len; + MTypeInfo atInfo; + MTypeInfo *tInfo = &atInfo; + PFIELDINFO fInfo, fInfo1, fInfo2; + + *vmt = false; *vmtAdr = 0; + classAdr = GetClassAdr(TypeName); + if (IsValidImageAdr(classAdr)) + { + *vmt = true; *vmtAdr = classAdr; + DWORD prevClassAdr = 0; + while (classAdr && Offset < GetClassSize(classAdr)) + { + prevClassAdr = classAdr; + classAdr = GetParentAdr(classAdr); + } + classAdr = prevClassAdr; + + if (classAdr) + { + *vmtAdr = classAdr; + PInfoRec recN = GetInfoRec(classAdr); + if (recN && recN->vmtInfo && recN->vmtInfo->fields) + { + if (recN->vmtInfo->fields->Count == 1) + { + fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[0]; + if (Offset == fInfo->Offset) + { + if (prefix != "") //Add by ZGL + fInfo->Name = prefix + "." + fInfo->Name; + return fInfo; + } + return 0; + } + for (int n = 0; n < recN->vmtInfo->fields->Count; n++) + { + fInfo1 = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; Ofs1 = fInfo1->Offset; + if (n == recN->vmtInfo->fields->Count - 1) + { + Ofs2 = GetClassSize(classAdr); + } + else + { + fInfo2 = (PFIELDINFO)recN->vmtInfo->fields->Items[n + 1]; + Ofs2 = fInfo2->Offset; + } + if (Offset >= Ofs1 && Offset < Ofs2) + { + if (Offset == Ofs1) return fInfo1; + kind = GetTypeKind(fInfo1->Type, &size); + if (kind == ikClass || kind == ikRecord) + { + prefix = fInfo1->Name; + fInfo = GetField(fInfo1->Type, Offset - Ofs1, vmt, vmtAdr, prefix); + if (fInfo) + { + fInfo->Offset = Offset; + if (prefix != "") //Add by ZGL + fInfo->Name = prefix + "." + fInfo->Name; + return fInfo; + } + return 0; + } + if (kind == ikArray) + return fInfo1; + return 0; + } + } + } + } + return 0; + } + + //try KB + uses = KnowledgeBase.GetTypeUses(TypeName.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, TypeName.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS, tInfo)) + if (tInfo->Fields) + { + p = tInfo->Fields; + for (n = 0; n < tInfo->FieldsNum; n++) + { + ps = p; + p++;//scope + Ofs1 = *((int*)p); p += 4;//offset + p += 4;//case + Len = *((WORD*)p); p += Len + 3;//name + Len = *((WORD*)p); p += Len + 3;//type + if (n == tInfo->FieldsNum - 1) + { + Ofs2 = 0; + } + else + { + Ofs2 = *((int*)(p + 1)); + } + if (Offset >= Ofs1 && Offset < Ofs2) + { + p = ps; + p++;//Scope + Ofs = *((int*)p); p += 4;//offset + fInfo = new FIELDINFO; + fInfo->Offset = Offset - Ofs; + fInfo->Scope = SCOPE_TMP; + fInfo->Case = *((int*)p); p += 4; + fInfo->xrefs = 0; + Len = *((WORD*)p); p += 2; + fInfo->Name = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + fInfo->Type = TrimTypeName(String((char*)p, Len)); + return fInfo; + } + } + return 0; + } + } + return 0; +} +//--------------------------------------------------------------------------- +PFIELDINFO __fastcall TFMain_11011981::AddField(DWORD ProcAdr, int ProcOfs, String TypeName, BYTE Scope, int Offset, int Case, String Name, String Type) +{ + DWORD classAdr = GetClassAdr(TypeName); + if (IsValidImageAdr(classAdr)) + { + if (Offset < 4) return 0; + + DWORD prevClassAdr = 0; + while (classAdr && Offset < GetClassSize(classAdr)) + { + prevClassAdr = classAdr; + classAdr = GetParentAdr(classAdr); + } + classAdr = prevClassAdr; + + if (classAdr) + { + PInfoRec recN = GetInfoRec(classAdr); + if (!recN) return 0; + if (!recN->vmtInfo) return 0; + return recN->vmtInfo->AddField(ProcAdr, ProcOfs, Scope, Offset, Case, Name, Type); + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miUnitDumperClick(TObject *Sender) +{ +; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miFuzzyScanKBClick(TObject *Sender) +{ + FKBViewer_11011981->Position = -1; + if (CurProcAdr) + { + PInfoRec recN = GetInfoRec(CurProcAdr); + if (recN && recN->kbIdx != -1) + { + FKBViewer_11011981->Position = recN->kbIdx; + FKBViewer_11011981->ShowCode(CurProcAdr, recN->kbIdx); + FKBViewer_11011981->Show(); + return; + } + + PUnitRec recU = GetUnit(CurProcAdr); + if (recU) + { + int fromAdr = recU->fromAdr, toAdr = recU->toAdr; + int upIdx = -1, dnIdx = -1, upCnt = -1, dnCnt = -1; + if (1)//!recU->names->Count) + { + if (FKBViewer_11011981->cbUnits->Text != "") + { + FKBViewer_11011981->cbUnitsChange(this); + } + else if (recU->names->Count) + { + FKBViewer_11011981->cbUnits->Text = recU->names->Strings[0]; + FKBViewer_11011981->cbUnitsChange(this); + } + if (FKBViewer_11011981->Position != -1) + { + FKBViewer_11011981->Show(); + } + else + { + for (int adr = CurProcAdr; adr >= fromAdr; adr--) + { + if (IsFlagSet(cfProcStart, Adr2Pos(adr))) + { + upCnt++; + recN = GetInfoRec(adr); + if (recN && recN->kbIdx != -1) + { + upIdx = recN->kbIdx; + break; + } + } + } + for (int adr = CurProcAdr; adr < toAdr; adr++) + { + if (IsFlagSet(cfProcStart, Adr2Pos(adr))) + { + dnCnt++; + recN = GetInfoRec(adr); + if (recN && recN->kbIdx != -1) + { + dnIdx = recN->kbIdx; + break; + } + } + } + if (upIdx != -1) + { + if (dnIdx != -1) + { + //Up proc is nearest + if (upCnt < dnCnt) + { + FKBViewer_11011981->Position = upIdx + upCnt; + FKBViewer_11011981->ShowCode(CurProcAdr, upIdx + upCnt); + FKBViewer_11011981->Show(); + } + //Down is nearest + else + { + FKBViewer_11011981->Position = dnIdx - dnCnt; + FKBViewer_11011981->ShowCode(CurProcAdr, dnIdx - dnCnt); + FKBViewer_11011981->Show(); + } + } + else + { + FKBViewer_11011981->Position = upIdx + upCnt; + FKBViewer_11011981->ShowCode(CurProcAdr, upIdx + upCnt); + FKBViewer_11011981->Show(); + } + } + else if (dnIdx != -1) + { + FKBViewer_11011981->Position = dnIdx - dnCnt; + FKBViewer_11011981->ShowCode(CurProcAdr, dnIdx - dnCnt); + FKBViewer_11011981->Show(); + } + //Nothing found! + else + { + FKBViewer_11011981->Position = -1; + FKBViewer_11011981->ShowCode(CurProcAdr, -1); + FKBViewer_11011981->Show(); + } + } + return; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::InitAliases(bool find) +{ + TCursor curCursor = Screen->Cursor; + Screen->Cursor = crHourGlass; + + if (find) ResInfo->InitAliases(); + + lClassName->Caption = ""; + lbAliases->Clear(); + + for (int n = 0; n < ResInfo->Aliases->Count; n++) + { + String item = ResInfo->Aliases->Strings[n]; + if (item.Pos("=")) + { + char *p = AnsiLastChar(item); + if (p && *p != '=') lbAliases->Items->Add(item); + } + } + + cbAliases->Clear(); + + for (int n = 0;; n++) + { + if (!RegClasses[n].RegClass) break; + + if (RegClasses[n].ClassName) + cbAliases->Items->Add(String(RegClasses[n].ClassName)); + } + + pnlAliases->Visible = false; + lbAliases->Enabled = true; + Screen->Cursor = curCursor; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbAliasesDblClick(TObject *Sender) +{ + lClassName->Caption = ""; + cbAliases->Text = ""; + String item = lbAliases->Items->Strings[lbAliases->ItemIndex]; + int pos = item.Pos("="); + if (pos) + { + pnlAliases->Visible = true; + lClassName->Caption = item.SubString(1, pos - 1); + cbAliases->Text = item.SubString(pos + 1, item.Length() - pos); + lbAliases->Enabled = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::bApplyAliasClick(TObject *Sender) +{ + ResInfo->Aliases->Values[lClassName->Caption] = cbAliases->Text; + pnlAliases->Visible = false; + lbAliases->Items->Strings[lbAliases->ItemIndex] = lClassName->Caption + "=" + cbAliases->Text; + lbAliases->Enabled = true; + + //as: we any opened Forms -> repaint (take into account new aliases) + ResInfo->ReopenAllForms(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::bCancelAliasClick(TObject *Sender) +{ + pnlAliases->Visible = false; + lbAliases->Enabled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miLegendClick(TObject *Sender) +{ + FLegend_11011981->ShowModal(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopyListClick(TObject *Sender) +{ + int n, m, k, u, dot, idx, usesNum; + PInfoRec recN; + PUnitRec recU; + MProcInfo aInfo; + MProcInfo *pInfo = &aInfo; + FILE *outFile; + TStringList *tmpList; + String moduleName, importName; + WORD uses[128]; + + SaveDlg->InitialDir = WrkDir; + SaveDlg->FileName = "units.lst"; + + if (SaveDlg->Execute()) + { + if (FileExists(SaveDlg->FileName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + outFile = fopen(SaveDlg->FileName.c_str(), "wt+"); + if (!outFile) + { + ShowMessage("Cannot save units list"); + return; + } + Screen->Cursor = crHourGlass; + tmpList = new TStringList; + for (n = 0; n < UnitsNum; n++) + { + recU = (UnitRec*)Units->Items[n]; + for (u = 0; u < recU->names->Count; u++) + { + if (tmpList->IndexOf(recU->names->Strings[u]) == -1) tmpList->Add(recU->names->Strings[u]); + } + //Add Imports + for (m = 0; m < CodeSize; m += 4) + { + if (IsFlagSet(cfImport, m)) + { + recN = GetInfoRec(Pos2Adr(m)); + dot = recN->GetName().Pos("."); + importName = recN->GetName().SubString(dot + 1, recN->GetNameLength()); + usesNum = KnowledgeBase.GetProcUses(importName.c_str(), uses); + for (k = 0; k < usesNum; k++) + { + idx = KnowledgeBase.GetProcIdx(uses[k], importName.c_str()); + if (idx != -1) + { + idx = KnowledgeBase.ProcOffsets[idx].NamId; + if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) + { + moduleName = KnowledgeBase.GetModuleName(pInfo->ModuleID); + if (tmpList->IndexOf(moduleName) == -1) tmpList->Add(moduleName); + } + } + } + } + } + tmpList->Sort(); + } + //Output result + for (n = 0; n < tmpList->Count; n++) + { + fprintf(outFile, "%s.dcu\n", tmpList->Strings[n].c_str()); + } + delete tmpList; + fclose(outFile); + Screen->Cursor = crDefault; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::wm_updAnalysisStatus(TMessage& msg) +{ + if (taUpdateUnits == msg.WParam) + { + const long isLastStep = msg.LParam; + tsUnits->Enabled = true; + ShowUnits(isLastStep); + ShowUnitItems(GetUnit(CurUnitAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + } + else if (taUpdateRTTIs == msg.WParam) + { + miSearchRTTI->Enabled = true; + miSortRTTI->Enabled = true; + tsRTTIs->Enabled = true; + ShowRTTIs(); + } + else if (taUpdateVmtList == msg.WParam) + { + FillVmtList(); + InitAliases(true); + } + else if (taUpdateStrings == msg.WParam) + { + tsStrings->Enabled = true; + miSearchString->Enabled = true; + ShowStrings(0); + tsNames->Enabled = true; + ShowNames(0); + } + else if (taUpdateCode == msg.WParam) + { + tsCodeView->Enabled = true; + bEP->Enabled = true; + DWORD adr = CurProcAdr; + CurProcAdr = 0; + ShowCode(adr, lbCode->ItemIndex, -1, lbCode->TopIndex); + } + else if (taUpdateXrefs == msg.WParam) + { + lbCXrefs->Enabled = true; + miGoTo->Enabled = true; + miExploreAdr->Enabled = true; + miSwitchFlag->Enabled = cbMultipleSelection->Checked; + } + else if (taUpdateShortClassViewer == msg.WParam) + { + tsClassView->Enabled = true; + miViewClass->Enabled = true; + miSearchVMT->Enabled = true; + miCollapseAll->Enabled = true; + + rgViewerMode->ItemIndex = 1; + rgViewerMode->Enabled = false; + } + else if (taUpdateClassViewer == msg.WParam) + { + tsClassView->Enabled = true; + miSearchVMT->Enabled = true; + miCollapseAll->Enabled = true; + + if (ClassTreeDone) + { + TTreeNode *root = tvClassesFull->Items->Item[0]; + root->Expanded = true; + miViewClass->Enabled = true; + rgViewerMode->ItemIndex = 0; + rgViewerMode->Enabled = true; + } + else + { + miViewClass->Enabled = true; + rgViewerMode->ItemIndex = 1; + rgViewerMode->Enabled = false; + } + miClassTreeBuilder->Enabled = true; + } + else if (taUpdateBeforeClassViewer == msg.WParam) + { + miSearchUnit->Enabled = true; + miRenameUnit->Enabled = true; + miSortUnits->Enabled = true; + miCopyList->Enabled = true; + miKBTypeInfo->Enabled = true; + miCtdPassword->Enabled = IsValidCodeAdr(CtdRegAdr); + miName->Enabled = true; + miViewProto->Enabled = true; + miEditFunctionC->Enabled = true; + miEditFunctionI->Enabled = true; + miEditClass->Enabled = true; + } + else if (taFinished == msg.WParam) + { + AnalyzeThreadDone(0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::wm_dfmClosed(TMessage& msg) +{ +} +//--------------------------------------------------------------------------- +//Fill ClassViewerTree for 1 class +void __fastcall TFMain_11011981::FillClassViewerOne(int n, TStringList* tmpList, const bool* terminated) +{ + bool vmtProc; + WORD _dx, _bx, _si; + int m, size, sizeParent, pos, cnt, vmtOfs, _pos; + DWORD vmtAdr, vmtAdrParent, vAdr, iAdr; + TTreeNode *rootNode, *node; + String className, nodeTextParent, nodeText, line, name; + PInfoRec recN; + PMethodRec recM; + PVmtListRec recV; + DISINFO disInfo; + + recV = (PVmtListRec)VmtList->Items[n]; + vmtAdr = recV->vmtAdr; + + className = GetClsName(vmtAdr); + + size = GetClassSize(vmtAdr); if (DelphiVersion >= 2009) size += 4; + + vmtAdrParent = GetParentAdr(vmtAdr); + sizeParent = GetClassSize(vmtAdrParent); if (DelphiVersion >= 2009) sizeParent += 4; + + nodeTextParent = GetParentName(vmtAdr) + " #" + Val2Str8(vmtAdrParent) + " Sz=" + Val2Str1(sizeParent); + nodeText = className + " #" + Val2Str8(vmtAdr) + " Sz=" + Val2Str1(size); + node = FindTreeNodeByName(nodeTextParent); + node = AddClassTreeNode(node, nodeText); + + rootNode = node; + + if (rootNode) + { + //Interfaces + const int intfsNum = LoadIntfTable(vmtAdr, tmpList); + if (intfsNum) + { + for (m = 0; m < intfsNum && !*terminated; m++) + { + nodeText = tmpList->Strings[m]; + sscanf(nodeText.c_str(), "%lX", &vAdr); + if (IsValidCodeAdr(vAdr)) + { + TTreeNode *intfsNode = AddClassTreeNode(rootNode, " " + nodeText.SubString(nodeText.Pos(' ') + 1, nodeText.Length())); + cnt = 0; + pos = Adr2Pos(vAdr); + for (int v = 0;;v += 4) + { + if (IsFlagSet(cfVTable, pos)) cnt++; + if (cnt == 2) break; + iAdr = *((DWORD*)(Code + pos)); + DWORD _adr = iAdr; + _pos = Adr2Pos(_adr); + vmtProc = false; vmtOfs = 0; + _dx = 0; _bx = 0; _si = 0; + while (1) + { + int instrlen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &disInfo, 0); + if ((disInfo.OpType[0] == otMEM || disInfo.OpType[1] == otMEM) && + disInfo.BaseReg != 20)//to exclude instruction "xchg reg, [esp]" + { + vmtOfs = disInfo.Offset; + } + if (disInfo.OpType[0] == otREG && disInfo.OpType[1] == otIMM) + { + if (disInfo.OpRegIdx[0] == 10)//dx + _dx = disInfo.Immediate; + else if (disInfo.OpRegIdx[0] == 11)//bx + _bx = disInfo.Immediate; + else if (disInfo.OpRegIdx[0] == 14)//si + _si = disInfo.Immediate; + } + if (disInfo.Call) + { + recN = GetInfoRec(disInfo.Immediate); + if (recN) + { + if (recN->SameName("@CallDynaInst") || + recN->SameName("@CallDynaClass")) + { + if (DelphiVersion <= 5) + GetDynaInfo(vmtAdr, _bx, &iAdr); + else + GetDynaInfo(vmtAdr, _si, &iAdr); + break; + } + else if (recN->SameName("@FindDynaInst") || + recN->SameName("@FindDynaClass")) + { + GetDynaInfo(vmtAdr, _dx, &iAdr); + break; + } + } + } + if (disInfo.Branch && !disInfo.Conditional) + { + if (IsValidImageAdr(disInfo.Immediate)) + { + iAdr = disInfo.Immediate; + } + else + { + vmtProc = true; + iAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr - cVmtSelfPtr + vmtOfs))); + recM = GetMethodInfo(vmtAdr, 'V', vmtOfs); + if (recM) name = recM->name; + } + break; + } + else if (disInfo.Ret) + { + vmtProc = true; + iAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr - cVmtSelfPtr + vmtOfs))); + recM = GetMethodInfo(vmtAdr, 'V', vmtOfs); + if (recM) name = recM->name; + break; + } + _pos += instrlen; _adr += instrlen; + } + if (!vmtProc && IsValidImageAdr(iAdr)) + { + recN = GetInfoRec(iAdr); + if (recN && recN->HasName()) + name = recN->GetName(); + else + name = ""; + } + line = "I" + Val2Str4(v) + " #" + Val2Str8(iAdr); + if (name != "") line += " " + name; + AddClassTreeNode(intfsNode, line); + pos += 4; + } + } + else + { + TTreeNode *intfsNode = AddClassTreeNode(rootNode, " " + nodeText); + } + } + } + if (*terminated) return; + //Automated + const int autoNum = LoadAutoTable(vmtAdr, tmpList); + if (autoNum) + { + nodeText = ""; + TTreeNode* autoNode = AddClassTreeNode(rootNode, nodeText); + for (m = 0; m < autoNum && !*terminated; m++) + { + nodeText = tmpList->Strings[m]; + AddClassTreeNode(autoNode, nodeText); + } + } + /* + //Fields + const int fieldsNum = form->LoadFieldTable(vmtAdr, fieldsList); + if (fieldsNum) + { + node = rootNode; + nodeText = ""; + //node = form->tvClassesFull->Items->AddChild(node, nodeText); + node = AddClassTreeNode(node, nodeText); + TTreeNode* fieldsNode = node; + for (m = 0; m < fieldsNum && !Terminated; m++) + { + //node = fieldsNode; + PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[m]; + nodeText = Val2Str5(fInfo->Offset) + " "; + if (fInfo->Name != "") + nodeText += fInfo->Name; + else + nodeText += "?"; + nodeText += ":"; + if (fInfo->Type != "") + nodeText += fInfo->Type; + else + nodeText += "?"; + + //node = form->tvClassesFull->Items->AddChild(node, nodeText); + AddClassTreeNode(fieldsNode, nodeText); + } + } + */ + if (*terminated) return; + //Events + const int methodsNum = LoadMethodTable(vmtAdr, tmpList); + if (methodsNum) + { + nodeText = ""; + TTreeNode* methodsNode = AddClassTreeNode(rootNode, nodeText); + for (m = 0; m < methodsNum && !*terminated; m++) + { + nodeText = tmpList->Strings[m]; + AddClassTreeNode(methodsNode, nodeText); + } + } + if (*terminated) return; + //Dynamics + const int dynamicsNum = LoadDynamicTable(vmtAdr, tmpList); + if (dynamicsNum) + { + nodeText = ""; + TTreeNode* dynamicsNode = AddClassTreeNode(rootNode, nodeText); + for (m = 0; m < dynamicsNum && !*terminated; m++) + { + nodeText = tmpList->Strings[m]; + AddClassTreeNode(dynamicsNode, nodeText); + } + } + if (*terminated) return; + //Virtual + const int virtualsNum = LoadVirtualTable(vmtAdr, tmpList); + if (virtualsNum) + { + nodeText = ""; + TTreeNode* virtualsNode = AddClassTreeNode(rootNode, nodeText); + for (m = 0; m < virtualsNum && !*terminated; m++) + { + nodeText = tmpList->Strings[m]; + AddClassTreeNode(virtualsNode, nodeText); + } + } + } +} +//--------------------------------------------------------------------------- +TTreeNode* __fastcall TFMain_11011981::AddClassTreeNode(TTreeNode* node, String nodeText) +{ + TTreeNode* newNode = 0; + if (!node) //Root + newNode = tvClassesFull->Items->Add(0, nodeText); + else + newNode = tvClassesFull->Items->AddChild(node, nodeText); + + AddTreeNodeWithName(newNode, nodeText); + + return newNode; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSaveDelphiProjectClick(TObject *Sender) +{ + bool typePresent, _isForm, comment; + BYTE kind; + int n, m, k, num, dotpos, len, minValue, maxValue; + DWORD adr, adr1, parentAdr; + FILE *f; + TList *tmpList; + TStringList *intBodyLines; + TStringList *intUsesLines; + //TStringList *impBodyLines; + //TStringList *impUsesLines; + TStringList *unitsList; + TStringList *formList; + TStringList *publishedList; + TStringList *publicList; + TSearchRec sr; + PUnitRec recU; + PInfoRec recN; + PFIELDINFO fInfo; + PMethodRec recM; + PVmtListRec recV; + TDfm *dfm; + PComponentInfo cInfo; + String curDir, DelphiProjectPath; + String unitName, className, parentName, fieldName, typeName; + String procName, formName, dfmName, line, uName; + + curDir = GetCurrentDir(); + DelphiProjectPath = AppDir + "Projects"; + if (DirectoryExists(DelphiProjectPath)) + { + ChDir(DelphiProjectPath); + if (!FindFirst("*.*", faArchive, sr)) + { + do + { + DeleteFile(sr.Name); + } while (!FindNext(sr)); + + FindClose(sr); + } + } + else + { + if (!CreateDir(DelphiProjectPath)) return; + ChDir(DelphiProjectPath); + } + Screen->Cursor = crHourGlass; + //Save Forms + for (n = 0; n < ResInfo->FormList->Count; n++) + { + dfm = (TDfm*)ResInfo->FormList->Items[n]; + formList = new TStringList; + ResInfo->GetFormAsText(dfm, formList); + dfmName = dfm->Name; + //If system name add F at start + if (SameText(dfmName, "prn")) dfmName = "F" + dfmName; + formList->SaveToFile(dfmName + ".dfm"); + delete formList; + } + + unitsList = new TStringList; + + for (n = 0; n < UnitsNum; n++) + { + recU = (PUnitRec)Units->Items[n]; + if (recU->trivial) continue; + typePresent = false; + _isForm = false; + unitName = GetUnitName(recU); + tmpList = new TList; + intBodyLines = new TStringList; + intUsesLines = new TStringList; + //impBodyLines = new TStringList; + //impUsesLines = new TStringList; + publishedList = new TStringList; + publicList = new TStringList; + + intUsesLines->Add("SysUtils"); + intUsesLines->Add("Classes"); + for (adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + recN = GetInfoRec(adr); + if (!recN) continue; + + kind = recN->kind; + switch (kind) + { + case ikEnumeration: + case ikSet: + case ikMethod: + case ikArray: + case ikRecord: + case ikDynArray: + typePresent = true; + line = FTypeInfo_11011981->GetRTTI(adr); + len = sprintf(StringBuf, " %s = %s;", recN->GetName().c_str(), line.c_str()); + intBodyLines->Add(String(StringBuf, len)); + break; + //class + case ikVMT: + typePresent = true; + className = recN->GetName(); + publishedList->Clear(); + publicList->Clear(); + + dfm = ResInfo->GetFormByClassName(className); + if (dfm) + { + _isForm = true; + len = sprintf(StringBuf, "%s in '%s.pas' {%s}", unitName, unitName, dfm->Name); + unitsList->Add(String(StringBuf, len)); + } + + parentAdr = GetParentAdr(adr); + parentName = GetClsName(parentAdr); + len = sprintf(StringBuf, " %s = class(%s)", className.c_str(), parentName.c_str()); + intBodyLines->Add(String(StringBuf, len)); + + num = LoadFieldTable(adr, tmpList); + for (m = 0; m < num; m++) + { + fInfo = (PFIELDINFO)tmpList->Items[m]; + if (fInfo->Name != "") + fieldName = fInfo->Name; + else + fieldName = "f" + Val2Str0(fInfo->Offset); + if (fInfo->Type != "") + { + comment = false; + typeName = TrimTypeName(fInfo->Type); + } + else + { + comment = true; + typeName = "?"; + } + //Add UnitName to UsesList if necessary + for (k = 0; k < VmtList->Count; k++) + { + recV = (PVmtListRec)VmtList->Items[k]; + if (recV && SameText(typeName, recV->vmtName)) + { + uName = GetUnitName(recV->vmtAdr); + if (intUsesLines->IndexOf(uName) == -1) + intUsesLines->Add(uName); + break; + } + } + + if (!comment) + len = sprintf(StringBuf, " %s:%s;//f%X", fieldName.c_str(), typeName.c_str(), fInfo->Offset); + else + len = sprintf(StringBuf, " //%s:%s;//f%X", fieldName.c_str(), typeName.c_str(), fInfo->Offset); + if (_isForm && dfm && dfm->IsFormComponent(fieldName)) + publishedList->Add(String(StringBuf, len)); + else + publicList->Add(String(StringBuf, len)); + + } + + num = LoadMethodTable(adr, tmpList); + for (m = 0; m < num; m++) + { + recM = (PMethodRec)tmpList->Items[m]; + recN = GetInfoRec(recM->address); + procName = recN->MakePrototype(recM->address, true, false, false, false, false); + if (!procName.Pos(":?")) + len = sprintf(StringBuf, " %s//%08lX", procName, recM->address); + else + len = sprintf(StringBuf, " //%s//%08lX", procName, recM->address); + publishedList->Add(String(StringBuf, len)); + } + + num = LoadVirtualTable(adr, tmpList); + for (m = 0; m < num; m++) + { + recM = (PMethodRec)tmpList->Items[m]; + //Check if procadr from other class + if (!IsOwnVirtualMethod(adr, recM->address)) continue; + + recN = GetInfoRec(recM->address); + procName = recN->MakeDelphiPrototype(recM->address, recM); + + len = sprintf(StringBuf, " "); + if (procName.Pos(":?")) len += sprintf(StringBuf + len, "//"); + len += sprintf(StringBuf + len, "%s", procName.c_str()); + if (recM->id >= 0) len += sprintf(StringBuf + len, "//v%X", recM->id); + len += sprintf(StringBuf + len, "//%08lX", recM->address); + + publicList->Add(String(StringBuf, len)); + } + + num = LoadDynamicTable(adr, tmpList); + for (m = 0; m < num; m++) + { + recM = (PMethodRec)tmpList->Items[m]; + recN = GetInfoRec(recM->address); + procName = recN->MakePrototype(recM->address, true, false, false, false, false); + PMsgMInfo _info = GetMsgInfo(recM->id); + if (_info && _info->msgname != "") + { + procName += String(" message ") + _info->msgname + ";"; + } + else + procName += " dynamic;"; + + if (!procName.Pos(":?")) + len = sprintf(StringBuf, " %s//%08lX", procName.c_str(), recM->address); + else + len = sprintf(StringBuf, " //%s//%08lX", procName.c_str(), recM->address); + publicList->Add(String(StringBuf, len)); + } + + if (publishedList->Count) + { + intBodyLines->Add(" published"); + for (m = 0; m < publishedList->Count; m++) + { + intBodyLines->Add(publishedList->Strings[m]); + } + } + if (publicList->Count) + { + intBodyLines->Add(" public"); + for (m = 0; m < publicList->Count; m++) + { + intBodyLines->Add(publicList->Strings[m]); + } + } + + for (adr1 = recU->fromAdr; adr1 < recU->toAdr; adr1++) + { + //Skip Initialization and Finalization procs + if (adr1 == recU->iniadr || adr1 == recU->finadr) continue; + recN = GetInfoRec(adr1); + if (!recN || !recN->procInfo) continue; + dotpos = recN->GetName().Pos("."); + if (!dotpos || !SameText(className, recN->GetName().SubString(1, dotpos - 1))) continue; + if ((recN->procInfo->flags & PF_VIRTUAL) || + (recN->procInfo->flags & PF_DYNAMIC) || + (recN->procInfo->flags & PF_EVENT)) + continue; + + if (recN->kind == ikConstructor || (recN->procInfo->flags & PF_METHOD)) + { + procName = recN->MakePrototype(adr1, true, false, false, false, false); + if (!procName.Pos(":?")) + len = sprintf(StringBuf, " %s//%08lX", procName.c_str(), adr1); + else + len = sprintf(StringBuf, " //%s//%08lX", procName.c_str(), adr1); + if (intBodyLines->IndexOf(String(StringBuf, len)) == -1) + intBodyLines->Add(String(StringBuf, len)); + } + } + intBodyLines->Add(" end;"); + break; + } + } + //Output information + f = fopen((unitName + ".pas").c_str(), "wt+"); + OutputDecompilerHeader(f); + fprintf(f, "unit %s;\n\n", unitName); + fprintf(f, "interface\n"); + //Uses + if (intUsesLines->Count) + { + fprintf(f, "\nuses\n "); + for (m = 0; m < intUsesLines->Count; m++) + { + if (m) fprintf(f, ", "); + fprintf(f, "%s", intUsesLines->Strings[m].c_str()); + } + fprintf(f, ";\n\n"); + } + //Type + if (typePresent) fprintf(f, "type\n"); + for (m = 0; m < intBodyLines->Count; m++) + { + fprintf(f, "%s\n", intBodyLines->Strings[m].c_str()); + } + //Other procs (not class members) + for (adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + //Skip Initialization and Finalization procs + if (adr == recU->iniadr || adr == recU->finadr) continue; + + recN = GetInfoRec(adr); + if (!recN || !recN->procInfo) continue; + + procName = recN->MakePrototype(adr, true, false, false, false, false); + if (!procName.Pos(":?")) + len = sprintf(StringBuf, " %s//%08lX", procName.c_str(), adr); + else + len = sprintf(StringBuf, " //%s//%08lX", procName.c_str(), adr); + + if (intBodyLines->IndexOf(String(StringBuf, len)) != -1) continue; + + fprintf(f, "%s\n", StringBuf); + } + + fprintf(f, "\nimplementation\n\n"); + if (_isForm) fprintf(f, "{$R *.DFM}\n\n"); + for (adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + //Initialization and Finalization procs + if (adr == recU->iniadr || adr == recU->finadr) continue; + + recN = GetInfoRec(adr); + if (!recN || !recN->procInfo) continue; + + kind = recN->kind; + if (kind == ikConstructor || + kind == ikDestructor || + kind == ikProc || + kind == ikFunc) + { + fprintf(f, "//%08lX\n", adr); + procName = recN->MakePrototype(adr, true, false, false, true, false); + if (!procName.Pos(":?")) + { + fprintf(f, "%s\n", procName); + fprintf(f, "begin\n"); + fprintf(f, "{*\n"); + OutputCode(f, adr, "", false); + fprintf(f, "*}\n"); + fprintf(f, "end;\n\n"); + } + else + { + fprintf(f, "{*%s\n", procName); + fprintf(f, "begin\n"); + OutputCode(f, adr, "", false); + fprintf(f, "end;*}\n\n"); + } + } + } + + if (!recU->trivialIni || !recU->trivialFin) + { + fprintf(f, "Initialization\n"); + if (!recU->trivialIni) + { + fprintf(f, "//%08lX\n", recU->iniadr); + fprintf(f, "{*\n"); + OutputCode(f, recU->iniadr, "", false); + fprintf(f, "*}\n"); + } + fprintf(f, "Finalization\n"); + if (!recU->trivialFin) + { + fprintf(f, "//%08lX\n", recU->finadr); + fprintf(f, "{*\n"); + OutputCode(f, recU->finadr, "", false); + fprintf(f, "*}\n"); + } + } + + fprintf(f, "end."); + fclose(f); + + delete tmpList; + delete intBodyLines; + delete intUsesLines; + //delete impBodyLines; + //delete impUsesLines; + delete publishedList; + delete publicList; + } + //dpr + recU = (PUnitRec)Units->Items[UnitsNum - 1]; + unitName = recU->names->Strings[0]; + f = fopen((unitName + ".dpr").c_str(), "wt+"); + + OutputDecompilerHeader(f); + + if (SourceIsLibrary) + fprintf(f, "library %s;\n\n", unitName); + else + fprintf(f, "program %s;\n\n", unitName); + + fprintf(f, "uses\n"); + fprintf(f, " SysUtils, Classes;\n\n"); + + fprintf(f, "{$R *.res}\n\n"); + + if (SourceIsLibrary) + { + bool _expExists = false; + for (n = 0; n < ExpFuncList->Count; n++) + { + PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[n]; + adr = recE->address; + if (IsValidImageAdr(adr)) + { + fprintf(f, "//%08lX\n", adr); + recN = GetInfoRec(adr); + if (recN) + { + fprintf(f, "%s\n", recN->MakePrototype(adr, true, false, false, true, false)); + fprintf(f, "begin\n"); + fprintf(f, "{*\n"); + OutputCode(f, adr, "", false); + fprintf(f, "*}\n"); + fprintf(f, "end;\n\n"); + _expExists = true; + } + else + { + fprintf(f, "//No information\n\n"); + } + } + } + if (_expExists) + { + fprintf(f, "exports\n"); + for (n = 0; n < ExpFuncList->Count; n++) + { + PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[n]; + adr = recE->address; + if (IsValidImageAdr(adr)) + { + recN = GetInfoRec(adr); + if (recN) + { + fprintf(f, "%s", recN->GetName()); + if (n < ExpFuncList->Count - 1) fprintf(f, ",\n"); + } + } + } + fprintf(f, ";\n\n"); + } + } + + fprintf(f, "//%08lX\n", EP); + fprintf(f, "begin\n"); + fprintf(f, "{*\n"); + OutputCode(f, EP, "", false); + fprintf(f, "*}\n"); + fprintf(f, "end.\n"); + fclose(f); + + delete unitsList; + + ChDir(curDir); + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::bDecompileClick(TObject *Sender) +{ + int procSize = GetProcSize(CurProcAdr); + if (procSize > 0) + { + TDecompileEnv *DeEnv = new TDecompileEnv(CurProcAdr, procSize, GetInfoRec(CurProcAdr)); + try + { + DeEnv->DecompileProc(); + } + catch(Exception &exception) + { + ShowCode(DeEnv->StartAdr, DeEnv->ErrAdr, lbCXrefs->ItemIndex, -1); + Application->ShowException(&exception); + } + DeEnv->OutputSourceCode(); + if (DeEnv->Alarm) + tsSourceCode->Highlighted = true; + else + tsSourceCode->Highlighted = false; + if (!DeEnv->ErrAdr) + pcWorkArea->ActivePage = tsSourceCode; + delete DeEnv; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miHex2DoubleClick(TObject *Sender) +{ + FHex2DoubleDlg_11011981->ShowModal(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::acFontAllExecute(TObject *Sender) +{ + FontsDlg->Font->Assign(lbCode->Font); + if (FontsDlg->Execute()) SetupAllFonts(FontsDlg->Font); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::SetupAllFonts(TFont* font) +{ + TListBox* formListBoxes[] = + { + lbUnits, + lbRTTIs, + lbForms, + lbAliases, + lbCode, + //lbStrings, + lbNames, + lbNXrefs, + lbSXrefs, + lbCXrefs, + lbSourceCode, + lbUnitItems, + 0 + }; + + TTreeView* formTreeViews[] = + { + tvClassesShort, + tvClassesFull, + 0 + }; + + for (int n = 0; formListBoxes[n]; n++) + { + formListBoxes[n]->Font->Assign(font); + } + + for (int n = 0; formTreeViews[n]; n++) + { + formTreeViews[n]->Font->Assign(font); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmUnitItemsPopup(TObject *Sender) +{ + miEditFunctionI->Enabled = (lbUnitItems->ItemIndex >= 0); + miCopyAddressI->Enabled = (lbUnitItems->ItemIndex >= 0); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::CopyAddress(String line, int ofs, int bytes) +{ + char buf[9], *p = buf; + + Clipboard()->Open(); + for (int n = 1; n <= bytes; n++) + { + *p = line[n + ofs]; p++; + } + *p = 0; + ((TUnicodeClipboard *)Clipboard())->AsUnicodeText = buf; + Clipboard()->Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopyAddressCodeClick(TObject *Sender) +{ + int bytes = (lbCode->ItemIndex) ? 8 : 0; + CopyAddress(lbCode->Items->Strings[lbCode->ItemIndex], 1, bytes); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ClearPassFlags() +{ + ClearFlags(cfPass0 | cfPass1 | cfPass2 | cfPass, 0, TotalSize); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopySource2ClipboardClick(TObject *Sender) +{ + Copy2Clipboard(lbSourceCode->Items, 0, false); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmCodePopup(TObject *Sender) +{ + int _ap; + DWORD _adr; + DISINFO _disInfo; + + miXRefs->Enabled = false; + miXRefs->Clear(); + + if (ActiveControl == lbCode) + { + if (lbCode->ItemIndex <= 0) return; + DWORD adr; + sscanf(lbCode->Items->Strings[lbCode->ItemIndex].c_str() + 2, "%lX", &adr); + if (adr != CurProcAdr && IsFlagSet(cfLoc, Adr2Pos(adr))) + { + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->xrefs && recN->xrefs->Count > 0) + { + miXRefs->Enabled = true; + miXRefs->Clear(); + for (int n = 0; n < recN->xrefs->Count; n++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; + _adr = recX->adr + recX->offset; + _ap = Adr2Pos(_adr); + Disasm.Disassemble(Code + _ap, (__int64)_adr, &_disInfo, 0); + TMenuItem* mi = new TMenuItem(pmCode); + mi->Caption = Val2Str8(_adr) + " " + _disInfo.Mnem; + mi->Tag = _adr; + mi->OnClick = GoToXRef; + miXRefs->Add(mi); + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::GoToXRef(TObject *Sender) +{ + TMenuItem* mi = (TMenuItem*)Sender; + DWORD Adr = mi->Tag; + if (Adr && IsValidCodeAdr(Adr)) + { + PROCHISTORYREC rec; + + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(CurProcAdr, Adr, lbCXrefs->ItemIndex, -1); + CodeHistoryPush(&rec); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbFormsClick(TObject *Sender) +{ + FormsSearchFrom = lbForms->ItemIndex; + WhereSearch = SEARCH_FORMS; +} +//--------------------------------------------------------------------------- + +void __fastcall TFMain_11011981::lbCodeClick(TObject *Sender) +{ + WhereSearch = SEARCH_CODEVIEWER; + + if (lbCode->ItemIndex <= 0) return; + + String prevItem = SelectedAsmItem; + SelectedAsmItem = ""; + String text = lbCode->Items->Strings[lbCode->ItemIndex]; + int textLen = text.Length(); + + TPoint cursorPos; + GetCursorPos(&cursorPos); + cursorPos = lbCode->ScreenToClient(cursorPos); + for (int n = 1, wid = 0; n <= textLen; n++) + { + int cwid = lbCode->Canvas->TextWidth(text[n]); + if (wid > cursorPos.x) + { + char c; + int beg = n - 1; + while (beg >= 1) + { + c = text[beg]; + if (!isalpha(c) && !isdigit(c) && c != '@') + { + beg++; + break; + } + beg--; + } + int end = beg; + while (end <= textLen) + { + c = text[end]; + if (!isalpha(c) && !isdigit(c) && c != '@') + { + end--; + break; + } + end++; + } + SelectedAsmItem = text.SubString(beg, end - beg + 1); + break; + } + wid += cwid; + } + if (SelectedAsmItem != prevItem) lbCode->Invalidate(); +} +//--------------------------------------------------------------------------- + +void __fastcall TFMain_11011981::pcInfoChange(TObject *Sender) +{ + switch (pcInfo->TabIndex) + { + case 0: WhereSearch = SEARCH_UNITS; + break; + case 1: WhereSearch = SEARCH_RTTIS; + break; + case 2: WhereSearch = SEARCH_FORMS; + break; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TFMain_11011981::pcWorkAreaChange(TObject *Sender) +{ + switch (pcWorkArea->TabIndex) + { + case 0: WhereSearch = SEARCH_CODEVIEWER; + break; + case 1: WhereSearch = SEARCH_CLASSVIEWER; + break; + case 2: WhereSearch = SEARCH_STRINGS; + break; + case 3: WhereSearch = SEARCH_NAMES; + break; + case 4: WhereSearch = SEARCH_SOURCEVIEWER; + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchFormClick(TObject *Sender) +{ + WhereSearch = SEARCH_FORMS; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < FormsSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(FormsSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (lbForms->ItemIndex == -1) + FormsSearchFrom = 0; + else + FormsSearchFrom = lbForms->ItemIndex; + + FormsSearchText = FindDlg_11011981->cbText->Text; + if (FormsSearchList->IndexOf(FormsSearchText) == -1) FormsSearchList->Add(FormsSearchText); + FindText(FormsSearchText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchNameClick(TObject *Sender) +{ + WhereSearch = SEARCH_NAMES; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < NamesSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(NamesSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (lbNames->ItemIndex == -1) + NamesSearchFrom = 0; + else + NamesSearchFrom = lbNames->ItemIndex; + + NamesSearchText = FindDlg_11011981->cbText->Text; + if (NamesSearchList->IndexOf(NamesSearchText) == -1) NamesSearchList->Add(NamesSearchText); + FindText(NamesSearchText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miPluginsClick(TObject *Sender) +{ + String PluginsPath = AppDir + "Plugins"; + if (!DirectoryExists(PluginsPath)) + { + if (!CreateDir(PluginsPath)) + { + ShowMessage("Cannot create subdirectory for plugins"); + return; + } + } + + ResInfo->FormPluginName = ""; + if (ResInfo->hFormPlugin) + { + FreeLibrary(ResInfo->hFormPlugin); + ResInfo->hFormPlugin = 0; + } + FPlugins->PluginsPath = PluginsPath; + FPlugins->PluginName = ""; + if (FPlugins->ShowModal() == mrOk) ResInfo->FormPluginName = FPlugins->PluginName; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopyStringsClick(TObject *Sender) +{ + //Copy2Clipboard(lbStrings->Items, 0, false); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miViewAllClick(TObject *Sender) +{ +; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbSourceCodeMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if (lbSourceCode->CanFocus()) ActiveControl = lbSourceCode; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::cbMultipleSelectionClick(TObject *Sender) +{ +// lbCode->MultiSelect = cbMultipleSelection->Checked; +// miSwitchFlag->Enabled = cbMultipleSelection->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbSourceCodeDrawItem(TWinControl *Control, + int Index, TRect &Rect, TOwnerDrawState State) +{ +/* + if (hHighlight && HighlightDrawItem) + { + HighlightDrawItem(DelphiLbId, Index, Rect, false); + } +*/ +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSwitchSkipFlagClick(TObject *Sender) +{ + DWORD _adr; + + if (lbCode->SelCount > 0) + { + for (int n = 0; n < lbCode->Count; n++) + { + if (lbCode->Selected[n]) + { + sscanf(lbCode->Items->Strings[n].c_str() + 2, "%lX", &_adr); + Flags[Adr2Pos(_adr)] ^= (cfDSkip | cfSkip); + } + } + RedrawCode(); + ProjectModified = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSwitchFrameFlagClick(TObject *Sender) +{ + DWORD _adr; + + if (lbCode->SelCount > 0) + { + for (int n = 0; n < lbCode->Count; n++) + { + if (lbCode->Selected[n]) + { + sscanf(lbCode->Items->Strings[n].c_str() + 2, "%lX", &_adr); + Flags[Adr2Pos(_adr)] ^= cfFrame; + } + } + RedrawCode(); + ProjectModified = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::cfTry1Click(TObject *Sender) +{ + DWORD _adr; + + if (lbCode->SelCount > 0) + { + for (int n = 0; n < lbCode->Count; n++) + { + if (lbCode->Selected[n]) + { + sscanf(lbCode->Items->Strings[n].c_str() + 2, "%lX", &_adr); + Flags[Adr2Pos(_adr)] ^= cfTry; + } + } + RedrawCode(); + ProjectModified = true; + } +} +//--------------------------------------------------------------------------- +/* +void __fastcall TFMain_11011981::ChangeDelphiHighlightTheme(TObject *Sender) +{ + TMenuItem* mi = (TMenuItem*)Sender; + ChangeTheme(DelphiLbId, mi->Tag); +} +//--------------------------------------------------------------------------- +*/ +void __fastcall TFMain_11011981::miProcessDumperClick(TObject *Sender) +{ + FActiveProcesses->ShowProcesses(); + FActiveProcesses->ShowModal(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbSourceCodeClick(TObject *Sender) +{ + WhereSearch = SEARCH_SOURCEVIEWER; + + if (lbSourceCode->ItemIndex <= 0) return; + + String prevItem = SelectedSourceItem; + SelectedSourceItem = ""; + String text = lbSourceCode->Items->Strings[lbSourceCode->ItemIndex]; + int textLen = text.Length(); + + TPoint cursorPos; + GetCursorPos(&cursorPos); + cursorPos = lbSourceCode->ScreenToClient(cursorPos); + + for (int n = 1, wid = 0; n <= textLen; n++) + { + int cwid = lbSourceCode->Canvas->TextWidth(text[n]); + if (wid > cursorPos.x) + { + char c; + int beg = n - 1; + while (beg >= 1) + { + c = text[beg]; + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.') + { + beg++; + break; + } + beg--; + } + int end = beg; + while (end <= textLen) + { + c = text[end]; + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.') + { + end--; + break; + } + end++; + } + SelectedSourceItem = text.SubString(beg, end - beg + 1); + break; + } + wid += cwid; + } + if (SelectedSourceItem != prevItem) lbSourceCode->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSetlvartypeClick(TObject *Sender) +{ + PInfoRec recN = GetInfoRec(CurProcAdr); + PLOCALINFO pLocInfo = recN->procInfo->GetLocal(SelectedSourceItem); + if (recN && recN->procInfo->locals && SelectedSourceItem != "") + { + String ftype = InputDialogExec("Enter Type of " + SelectedSourceItem, "Type", pLocInfo->TypeDef).Trim(); + pLocInfo->TypeDef = ftype; + recN->procInfo->SetLocalType(pLocInfo->Ofs, ftype); + bDecompileClick(this); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmSourceCodePopup(TObject *Sender) +{ + PLOCALINFO pLocalInfo; + + PInfoRec recN = GetInfoRec(CurProcAdr); + if (recN && recN->procInfo->locals && SelectedSourceItem != "") + pLocalInfo = recN->procInfo->GetLocal(SelectedSourceItem); + + miSetlvartype->Enabled = (pLocalInfo); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopytoClipboardNamesClick( + TObject *Sender) +{ + Copy2Clipboard(lbNames->Items, 0, false); +} +//--------------------------------------------------------------------------- +//Added by TerminatorX 30.12.2018 +//TerminatorX code BEGIN +void __fastcall TFMain_11011981::miHiewGeneratorClick(TObject *Sender) +{ + int _posNamet; + String procName; + String nametName = ""; + String SourceFileNamet = ""; + String moduleName = ""; + + if (SourceFile != "") nametName = ChangeFileExt(SourceFile, ".namet"); + if (IDPFile != "") nametName = ChangeFileExt(IDPFile, ".namet"); + + SaveDlg->InitialDir = WrkDir; + SaveDlg->Filter = "NAMET|*.namet"; + SaveDlg->FileName = nametName; + + if (!SaveDlg->Execute()) return; + nametName = SaveDlg->FileName; + if (FileExists(nametName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO+MB_ICONWARNING) == IDNO) return; + } + Screen->Cursor = crHourGlass; + FILE *fNamet = fopen(nametName.c_str(), "wt+"); + if (!fNamet) + { + MessageDlg("Cannot open namet file", mtWarning, TMsgDlgButtons() << mbOK, 0); + return; + } + SourceFileNamet = SourceFile; + _posNamet = SourceFileNamet.LastDelimiter(""); + if (_posNamet) SourceFileNamet = SourceFileNamet.SubString(_posNamet + 1, SourceFileNamet.Length()); + for (int n = 0; n < CodeSize; n++) + { + if (IsFlagSet(cfProcStart, n) && !IsFlagSet(cfEmbedded, n)) + { + int adr = Pos2Adr(n); + PInfoRec recN = GetInfoRec(adr); + if (recN) + { + if (adr == EP) + fprintf(fNamet, ".%08X Entry Point_%08X\n", adr, adr); + else + { + PUnitRec recU = GetUnit(adr); + if (recU) + { + moduleName = GetUnitName(recU); + if (adr == recU->iniadr) + procName = "Initialization"; + else if (adr == recU->finadr) + procName = "Finalization"; + else + procName = recN->MakeMapName(adr); + } + else + { + moduleName = ""; + procName = recN->MakeMapName(adr); + } + if (moduleName != "") + fprintf(fNamet, ".%08X %s.%s_%08X\n", adr, moduleName.c_str(), procName.c_str(), adr); + else + fprintf(fNamet, ".%08X %s_%08X\n", adr, procName.c_str(), adr); + } + } + } + } + fclose(fNamet); + Screen->Cursor = crDefault; +} +//TerminatorX code END +//--------------------------------------------------------------------------- +//Added by TerminatorX 30.12.2018 +//TerminatorX code BEGIN +void __fastcall TFMain_11011981::mniShellIntegration1Click(TObject *Sender) +{ + if (!mniShellIntegration1->Checked) + { + TRegistry *reg = new TRegistry(KEY_ALL_ACCESS); + reg->RootKey = HKEY_CLASSES_ROOT; + reg->OpenKey("\exefile\shell\Open with IDR\command", true); + reg->WriteString("",(ExtractFilePath(Application->ExeName) + "Idr.exe %1")); + reg->CloseKey(); + + reg->OpenKey("\dllfile\shell\Open with IDR\command", true); + reg->WriteString("",(ExtractFilePath(Application->ExeName) + "Idr.exe %1")); + reg->CloseKey(); + delete reg; + mniShellIntegration1->Checked = true; + } + else + { + TRegistry *reg = new TRegistry(KEY_ALL_ACCESS); + reg->RootKey=HKEY_CLASSES_ROOT; + reg->DeleteKey("\exefile\shell\Open with IDR"); + reg->DeleteKey("\dllfile\shell\Open with IDR"); + delete reg; + mniShellIntegration1->Checked = false; + } +} +//TerminatorX code END +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::mCreateCHeaderFileClick(TObject *Sender) +{ + String hName = ""; + if (SourceFile != "") + { + hName = ChangeFileExt(SourceFile, ".h"); + } + if (IDPFile != "") + { + hName = ChangeFileExt(IDPFile, ".h"); + } + + TSaveDialog* SaveHDialog = new TSaveDialog(this); + SaveHDialog-> InitialDir = WrkDir; + SaveHDialog->Filter = "H|*.h"; + SaveHDialog->FileName = hName; + + if (!SaveHDialog->Execute()) return; + + hName = SaveHDialog->FileName; + delete SaveHDialog; + + if (FileExists(hName)) + { + if (Application->MessageBox("File already exists. Overwrite?", "Warning", MB_YESNO) == IDNO) return; + } + + Screen->Cursor = crHourGlass; + + FILE* hF = fopen(hName.c_str(), "wt+"); + CreateCppHeaderFile(hF); + fclose(hF); + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +typedef struct +{ + char* CppType; + char* DelphiType; +} CPPvsDELPHIdecl; + +CPPvsDELPHIdecl ForwardDeclarations[] = { + {"bool", "Boolean"}, + {"char", "AnsiChar"}, + {"signed char", "ShortInt"}, + {"unsigned char", "ByteBool"}, + {"unsigned char", "Byte"}, + {"short", "SmallInt"}, + {"unsigned short", "Word"}, + {"unsigned short", "word"}, + {"unsigned short", "WordBool"}, + {"int", "Integer"}, + {"int", "NativeInt"}, + {"int", "LongInt"}, + {"int", "FixedInt"}, + {"unsigned", "Dword"}, + {"unsigned", "dword"}, + {"unsigned", "LongBool"}, + {"unsigned", "Cardinal"}, + {"unsigned int", "NativeUInt"}, + {"unsigned", "LongWord"}, + {"unsigned int", "FixedUInt"}, + {"char*", "AnsiString"}, + {"char*", "OpenString"}, + {"wchar_t*", "String"}, + {"wchar_t*", "string"}, + {"wchar_t*", "WideString"}, + {"wchar_t*", "UString"}, + {"wchar_t*", "UnicodeString"}, + {"wchar_t", "Char"}, + {"wchar_t", "WideChar"}, + {"void*", "Pointer"}, + {"__int64", "Int64"}, + {"unsigned __int64", "UInt64"}, + {"unsigned __int64", "Currency"}, + {"unsigned __int64", "Comp"}, + {"unsigned __int64", "TDateTime"}, + {"unsigned __int64", "TDate"}, + {"unsigned __int64", "TTime"}, + {"float", "Single"}, + {"double", "Double"}, + {"long double", "Extended"}, + {"double", "Real"}, + {NULL, NULL} +}; +//--------------------------------------------------------------------------- +void __fastcall OutputStandardForwardDeclarations(FILE* hF) +{ + for (int n = 0;; n++) + { + if (!ForwardDeclarations[n].CppType) break; + fprintf(hF, "typedef %s %s;\n", ForwardDeclarations[n].CppType, ForwardDeclarations[n].DelphiType); + } +} +//--------------------------------------------------------------------------- +bool __fastcall IsStandardForwardDeclaration(String name) +{ + bool bRes = false; + for (int n = 0;; n++) + { + if (!ForwardDeclarations[n].CppType) break; + if (SameText(name, ForwardDeclarations[n].DelphiType)) + { + bRes = true; + break; + } + } + return bRes; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::OutputForwardDeclarationsHeader(FILE* hF) +{ + fprintf(hF, "//This file was created by IDR.\n"); + fprintf(hF, "//It may require manually editing, because of arrays and order mismatching.\n"); + fprintf(hF, "//It is not so hard.\n"); + fprintf(hF, "//But You reach main goal - decompilation with IDA!\n\n"); + fprintf(hF, "//Symbol | points to places in records that belongs to union.\n"); + fprintf(hF, "//You can leave only one variant or try convert to union (question is why?).\n\n"); + + OutputStandardForwardDeclarations(hF); + fprintf(hF, "\n"); + //Variant + fprintf(hF, "struct TVarData\n"); + fprintf(hF, "{\n"); + fprintf(hF, "WORD VType;\n"); + fprintf(hF, "WORD Reserved1;\n"); + fprintf(hF, "WORD Reserved2;\n"); + fprintf(hF, "WORD Reserved3;\n"); + fprintf(hF, "BYTE Data[8];\n"); + fprintf(hF, "};\n"); + fprintf(hF, "typedef TVarData Variant;\n\n"); + fprintf(hF, "struct TVarRec\n"); + fprintf(hF, "{\n"); + fprintf(hF, "Integer Data;\n"); + fprintf(hF, "Integer Type;\n"); + fprintf(hF, "};\n\n"); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::OutputForwardDeclarationsOfKind(FILE* hF, BYTE kind) +{ + int n, size, typeKind; + DWORD adr; + PTypeRec recT; + String str, RTTIName; + + for (n = 0; n < OwnTypeList->Count; n++) + { + recT = (PTypeRec)OwnTypeList->Items[n]; + if (recT->kind == kind) + { + adr = recT->adr; + RTTIName = recT->name; + if (IsStandardForwardDeclaration(RTTIName)) + continue; + + RTTIName = SanitizeName(RTTIName); + switch (kind) + { + case ikInteger: + case ikChar: + case ikWChar: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "typedef %s %s;\n", str.c_str(), RTTIName.c_str()); + break; + case ikEnumeration: + //shadow name + if (RTTIName.Pos(":") > 0) + RTTIName = "Enum_" + Val2Str8(adr); + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "enum %s : ", RTTIName.c_str()); + if (size <= 255) + fprintf(hF, "BYTE"); + else + fprintf(hF, "WORD"); + fprintf(hF, "\n{\n%s\n};\n\n", str.c_str()); + break; + case ikString: + case ikLString: + if (!SameText(RTTIName, "String") && !SameText(RTTIName, "AnsiString")) + fprintf(hF, "typedef String %s;\n", RTTIName.c_str()); + break; + case ikWString: + if (!SameText(RTTIName, "WideString")) + fprintf(hF, "typedef WideString %s;\n", RTTIName.c_str()); + break; + case ikUString: + if (!SameText(RTTIName, "UString") && !SameText(RTTIName, "String")) + fprintf(hF, "typedef UString %s;\n", RTTIName.c_str()); + break; + case ikSet: + //shadow name + if (RTTIName.Pos(":") > 0) + RTTIName = "Set_" + Val2Str8(adr); + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 1); + if (str != "") + { + fprintf(hF, "enum %s : ", RTTIName.c_str()); + if (size <= 8) + fprintf(hF, "BYTE"); + else if (size <= 16) + fprintf(hF, "WORD"); + else if (size <= 32) + fprintf(hF, "DWORD"); + else if (size <= 64) + fprintf(hF, "QWORD"); + else if (size <= 128) + fprintf(hF, "__int128"); + else + fprintf(hF, "__int256"); + fprintf(hF, "\n{\n%s\n};\n\n", str.c_str()); + } + break; + case ikRecord: + case ikClass: + fprintf(hF, "struct %s;\n", RTTIName.c_str()); + break; + case ikMethod: + fprintf(hF, "struct %s\n", RTTIName.c_str()); + fprintf(hF, "{\n"); + fprintf(hF, "void* p;\n"); + fprintf(hF, "DWORD m;\n"); + fprintf(hF, "};\n\n"); + break; + case ikPointer: + break; + case ikDynArray: + break; + case ikArray: + break; + case ikProcedure: + break; + case ikInterface: + fprintf(hF, "struct %s_vt\n", RTTIName.c_str()); + fprintf(hF, "{\n"); + fprintf(hF, "void* QueryInterface;\n"); + fprintf(hF, "void* AddRef;\n"); + fprintf(hF, "void* Release;\n"); + fprintf(hF, "};\n"); + fprintf(hF, "typedef %s_vt *%s;\n\n", RTTIName.c_str(), RTTIName.c_str()); + break; + case ikVariant: + fprintf(hF, "typedef Variant %s;\n", RTTIName.c_str()); + break; + } + } + } +} +//--------------------------------------------------------------------------- +typedef struct _VMT_PROC +{ + DWORD Adr; + int CurIdx; + BYTE Multiple; +} VMT_PROC, *PVMT_PROC; +//--------------------------------------------------------------------------- +PVMT_PROC __fastcall GetProcFromVmtList(TList* list, DWORD procAdr) +{ + PVMT_PROC Result = 0; + + for (int n = 0; n < list->Count; n++) + { + PVMT_PROC vmtProc = (PVMT_PROC)list->Items[n]; + if (vmtProc->Adr == procAdr) + { + Result = vmtProc; + break; + } + } + return Result; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::CreateCppHeaderFile(FILE* hF) +{ + BYTE len, RTTIKind; + int n, m, k, id, adr, kind, pos, size, sort, virtNum, idx, intfNum, curOfs, nxtOfs, iAdr; + DWORD* intfOfsets; + PUnitRec recU; + PInfoRec recN; + String unitName, RTTIName, str, name, item; + PFIELDINFO fInfo; + TList* virtList; + TList* vmtProcs; + TStringList* intfList; + PMethodRec recM; + PVMT_PROC vmtProc; + + //Save sort style + sort = RTTISortField; + OwnTypeList->Sort(SortRTTIsByAdr); + OutputForwardDeclarationsHeader(hF); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikInteger); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikChar); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikWChar); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikString); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikLString); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikWString); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikUString); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikVariant); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikEnumeration); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikSet); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikClass); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikRecord); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikMethod); + fprintf(hF, "//\n"); + OutputForwardDeclarationsOfKind(hF, ikInterface); + //Restore old sort style + RTTISortField = sort; + switch (RTTISortField) + { + case 0: + OwnTypeList->Sort(SortRTTIsByAdr); + break; + case 1: + OwnTypeList->Sort(SortRTTIsByKnd); + break; + case 2: + OwnTypeList->Sort(SortRTTIsByNam); + break; + } + + for (int n = 0; n < UnitsNum; n++) + { + recU = (PUnitRec)Units->Items[n]; + if (recU->trivial) continue; + unitName = GetUnitName(recU); + fprintf(hF, "//%s\n", unitName.c_str()); + + for (adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + recN = GetInfoRec(adr); + if (!recN) continue; + + kind = recN->kind; + if (kind != ikVMT) + { + pos = Adr2Pos(adr) + 4 + 1; + len = Code[pos]; pos++; + RTTIName = String((char*)(Code + pos), len); + } + else + RTTIName = recN->GetName(); + + if (IsStandardForwardDeclaration(RTTIName)) + continue; + + RTTIName = SanitizeName(RTTIName); + size = 0; + if (kind != ikVMT) continue; + switch (kind) + { + case ikInteger: + case ikChar: + case ikWChar: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "typedef %s %s;\n\n", str.c_str(), RTTIName.c_str()); + break; + case ikEnumeration: + break; + case ikSet: + break; + case ikProcedure: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "typedef %s;\n", str.c_str()); + break; + case ikMethod: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "typedef %s;\n", str.c_str()); + fprintf(hF, "struct %s\n", RTTIName.c_str()); + fprintf(hF, "{\n"); + fprintf(hF, "P%s p;\n", RTTIName.c_str()); + fprintf(hF, "DWORD m;\n"); + fprintf(hF, "};\n\n"); + break; + case ikArray: + if (RTTIName.Pos(":") > 0) + RTTIName = "Array_" + Val2Str8(adr); + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, str.c_str(), RTTIName.c_str()); + break; + case ikRecord: + //These names already present + if (SameText(RTTIName, "TVarData") || + SameText(RTTIName, "TVarRec")) + { + break; + } + //shadow name + if (RTTIName.Pos(":") > 0) + RTTIName = "Record_" + Val2Str8(adr);//SHADOW + 4 + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + if (size > 10000) fprintf(hF, "//Big size!\n"); + fprintf(hF, "struct %s//size=0x%s\n", RTTIName.c_str(), Val2Str0(size)); + fprintf(hF, "{\n"); + fprintf(hF, "%s", str.c_str()); + fprintf(hF, "};\n\n"); + break; + case ikInt64: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "typedef %s %s;\n\n", str.c_str(), RTTIName.c_str()); + break; + case ikDynArray: + if (RTTIName.Pos(":") > 0) + RTTIName = "DynArray_" + Val2Str8(adr); + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + kind = GetTypeKind(str, &size); + fprintf(hF, "typedef "); + if (kind == ikRecord || kind == ikVMT) + fprintf(hF, "struct "); + fprintf(hF, "%s *", str.c_str()); + if (kind == ikVMT) + fprintf(hF, "*"); + fprintf(hF, "%s;\n\n", RTTIName.c_str()); + break; + case ikPointer: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + kind = GetTypeKind(str, &size); + fprintf(hF, "typedef "); + if (kind == ikRecord || kind == ikVMT) + fprintf(hF, "struct "); + fprintf(hF, "%s *%s;\n", str.c_str(), RTTIName.c_str()); + break; + case ikClassRef: + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "typedef struct %s *%s;\n\n", str.c_str(), RTTIName.c_str()); + break; + case ikVMT: + //Output virtual functions + virtList = new TList; + virtNum = LoadVirtualTable(adr, virtList); + //Fill VMT_PROCS list + vmtProcs = new TList; + for (m = 0, id = 0; m < virtNum; m++) + { + recM = (PMethodRec)virtList->Items[m]; + if (recM->id >= 0) + { + vmtProc = GetProcFromVmtList(vmtProcs, recM->address); + if (!vmtProc) + { + vmtProc = new VMT_PROC; + vmtProc->Adr = recM->address; + vmtProc->CurIdx = 0; + vmtProc->Multiple = 0; + vmtProcs->Add((void*)vmtProc); + } + else + { + vmtProc->Multiple = 1; + } + } + } + //Output function prorotype declarations + for (m = 0, id = 0; m < virtNum; m++) + { + recM = (PMethodRec)virtList->Items[m]; + if (recM->id >= 0) + { + fprintf(hF, "typedef "); + recN = GetInfoRec(recM->address); + if (recN) + { + str = recN->MakeCppPrototype(recM->address, RTTIName + "_m" + Val2Str0(id)); + fprintf(hF, "%s", str.c_str()); + } + else + { + fprintf(hF, "DWORD (__usercall *P%s_m%d)@", RTTIName.c_str(), id); + } + fprintf(hF, ";\n"); + id += 4; + } + } + + fprintf(hF, "struct %s_vmt\n", RTTIName.c_str()); + fprintf(hF, "{\n"); + for (m = 0, id = 0; m < virtNum; m++) + { + recM = (PMethodRec)virtList->Items[m]; + if (recM->id >= 0) + { + name = recM->name; + recN = GetInfoRec(recM->address); + vmtProc = GetProcFromVmtList(vmtProcs, recM->address); + idx = -1; + if (vmtProc && vmtProc->Multiple) + { + idx = vmtProc->CurIdx; + vmtProc->CurIdx++; + } + if (recN) + { + if (name == "") + name = recN->GetName(); + fprintf(hF, "P%s_m%lX %s_sub_%08lX", RTTIName.c_str(), id, RTTIName.c_str(), recM->address); + if (idx >= 0) + fprintf(hF, "_%d", idx); + fprintf(hF, ";"); + if (name != "") + fprintf(hF, "//%s", name.c_str()); + } + else + { + fprintf(hF, "P%s_m%lX %s_sub_%08lX", RTTIName.c_str(), id, RTTIName.c_str(), recM->address); + if (idx >= 0) + fprintf(hF, "_%d", idx); + fprintf(hF, ";"); + if (name != "") + fprintf(hF, "//%s", name.c_str()); + } + fprintf(hF, "\n"); + id += 4; + } + } + fprintf(hF, "};\n\n"); + delete vmtProcs; + delete virtList; + + //Output fields + str = FTypeInfo_11011981->GetCppTypeInfo(adr, &size, 0); + fprintf(hF, "struct %s//size = 0x%lX\n", RTTIName.c_str(), GetClassSize(adr)); + fprintf(hF, "{\n"); + fprintf(hF, "%s", str.c_str()); + fprintf(hF, "};\n\n"); + + //Output Interfaces + intfList = new TStringList; + intfNum = FMain_11011981->LoadIntfTable(adr, intfList); + if (intfNum > 0) + { + intfOfsets = new DWORD[intfNum]; + for (m = 0; m < intfNum; m++) + { + item = intfList->Strings[m]; + item = item.SubString(1, item.Pos(' ') - 1); + //Offset of interface table + intfOfsets[m] = StrToInt("$" + item); + } + if (intfNum > 1) + { + for (m = 0; m < intfNum - 1; m++) + { + curOfs = intfOfsets[m]; + nxtOfs = intfOfsets[m + 1]; + if (!curOfs || curOfs == nxtOfs) + continue; + + fprintf(hF, "struct Interface_%08lX\n", curOfs); + fprintf(hF, "{\n"); + fprintf(hF, "struct Interface_%08lX_vt* v;\n", curOfs); + fprintf(hF, "};\n\n"); + + fprintf(hF, "struct Interface_%08lX_vt\n", curOfs); + fprintf(hF, "{\n"); + + for (k = curOfs; k < nxtOfs; k += 4) + { + iAdr = *((DWORD*)(Code + Adr2Pos(k))); + fprintf(hF, "void* sub_%08lX;\n", iAdr); + } + + fprintf(hF, "};\n\n"); + } + } + curOfs = intfOfsets[intfNum - 1]; + fprintf(hF, "struct Interface_%08lX\n", curOfs); + fprintf(hF, "{\n"); + fprintf(hF, "struct Interface_%08lX_vt* v;\n", curOfs); + fprintf(hF, "};\n\n"); + + fprintf(hF, "struct Interface_%08lX_vt\n", curOfs); + fprintf(hF, "{\n"); + + for (k = curOfs;; k += 4) + { + iAdr = *((DWORD*)(Code + Adr2Pos(k))); + if (!IsValidCodeAdr(iAdr)) + break; + + fprintf(hF, "void* sub_%08lX;\n", iAdr); + } + + fprintf(hF, "};\n\n"); + delete[] intfOfsets; + } + delete intfList; + break; + } + } + } +} +//--------------------------------------------------------------------------- diff --git a/Sources/Forms/Main.dfm b/Main.dfm similarity index 90% rename from Sources/Forms/Main.dfm rename to Main.dfm index 560cf2a..dfcd91a 100644 --- a/Sources/Forms/Main.dfm +++ b/Main.dfm @@ -1,9 +1,9 @@ object FMain_11011981: TFMain_11011981 - Left = 907 - Top = 55 + Left = 243 + Top = 124 + Width = 1033 + Height = 855 Caption = 'Interactive Delphi Reconstructor' - ClientHeight = 755 - ClientWidth = 1017 Color = clBtnFace DefaultMonitor = dmDesktop Font.Charset = DEFAULT_CHARSET @@ -14,7 +14,7 @@ object FMain_11011981: TFMain_11011981 KeyPreview = True Menu = MainMenu OldCreateOrder = False - Position = poScreenCenter + Position = poDefault OnClose = FormClose OnCloseQuery = FormCloseQuery OnCreate = FormCreate @@ -26,7 +26,7 @@ object FMain_11011981: TFMain_11011981 TextHeight = 13 object SplitterH1: TSplitter Left = 0 - Top = 605 + Top = 647 Width = 1017 Height = 4 Cursor = crVSplit @@ -36,26 +36,27 @@ object FMain_11011981: TFMain_11011981 Color = clGray MinSize = 100 ParentColor = False - ExplicitTop = 705 end object SplitterV1: TSplitter Left = 250 Top = 0 - Height = 605 + Width = 3 + Height = 647 + Cursor = crHSplit AutoSnap = False Beveled = True Color = clGray MinSize = 3 ParentColor = False - ExplicitHeight = 705 end object pcWorkArea: TPageControl Left = 253 Top = 0 Width = 764 - Height = 605 - ActivePage = tsCodeView + Height = 647 + ActivePage = tsClassView Align = alClient + TabIndex = 1 TabOrder = 1 OnChange = pcWorkAreaChange object tsCodeView: TTabSheet @@ -64,7 +65,7 @@ object FMain_11011981: TFMain_11011981 Left = 0 Top = 25 Width = 646 - Height = 552 + Height = 594 Cursor = crIBeam Style = lbOwnerDrawFixed AutoComplete = False @@ -77,6 +78,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 16 ParentFont = False ParentShowHint = False PopupMenu = pmCode @@ -187,7 +189,7 @@ object FMain_11011981: TFMain_11011981 Left = 646 Top = 25 Width = 110 - Height = 552 + Height = 594 Style = lbOwnerDrawFixed Align = alRight Anchors = [] @@ -197,6 +199,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 16 ParentFont = False TabOrder = 2 OnDblClick = lbXrefsDblClick @@ -208,15 +211,11 @@ object FMain_11011981: TFMain_11011981 object tsClassView: TTabSheet Caption = 'ClassViewer (F7)' ImageIndex = 1 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object tvClassesFull: TTreeView Left = 0 Top = 40 Width = 756 - Height = 557 + Height = 579 Align = alClient Color = clWhite Font.Charset = DEFAULT_CHARSET @@ -261,7 +260,7 @@ object FMain_11011981: TFMain_11011981 Left = 0 Top = 40 Width = 756 - Height = 537 + Height = 579 Align = alClient Color = clWhite Font.Charset = DEFAULT_CHARSET @@ -285,31 +284,27 @@ object FMain_11011981: TFMain_11011981 object tsStrings: TTabSheet Caption = 'Strings (F8)' ImageIndex = 2 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 - object lbStrings: TListBox + object lbStrings: TTntListBox Left = 0 Top = 25 Width = 646 - Height = 572 - Style = lbOwnerDrawFixed + Height = 594 AutoComplete = False Align = alClient Anchors = [] Color = clWhite - Font.Charset = DEFAULT_CHARSET + Font.Charset = ANSI_CHARSET Font.Color = clWindowText Font.Height = -12 - Font.Name = 'Courier New' + Font.Name = 'Fixedsys' Font.Style = [] + ItemHeight = 16 + MultiSelect = True ParentFont = False PopupMenu = pmStrings TabOrder = 0 OnClick = lbStringsClick OnDblClick = lbStringsDblClick - OnDrawItem = lbStringsDrawItem OnMouseMove = lbStringsMouseMove end object Panel3: TPanel @@ -335,7 +330,7 @@ object FMain_11011981: TFMain_11011981 Left = 646 Top = 25 Width = 110 - Height = 552 + Height = 594 Style = lbOwnerDrawFixed Align = alRight Anchors = [] @@ -344,6 +339,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 16 ParentFont = False TabOrder = 2 OnDblClick = lbXrefsDblClick @@ -356,15 +352,11 @@ object FMain_11011981: TFMain_11011981 Caption = 'Items' ImageIndex = 3 TabVisible = False - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object sgItems: TStringGrid Left = 0 Top = 0 - Width = 756 - Height = 597 + Width = 657 + Height = 363 Align = alClient DefaultRowHeight = 16 FixedCols = 0 @@ -377,23 +369,16 @@ object FMain_11011981: TFMain_11011981 64 538 21) - RowHeights = ( - 16 - 16) end end object tsNames: TTabSheet Caption = 'Names (F9)' ImageIndex = 4 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object lbNames: TListBox Left = 0 Top = 25 Width = 646 - Height = 572 + Height = 594 AutoComplete = False Align = alClient Anchors = [] @@ -404,6 +389,7 @@ object FMain_11011981: TFMain_11011981 Font.Style = [] ItemHeight = 15 ParentFont = False + PopupMenu = pmNames TabOrder = 0 OnClick = lbNamesClick end @@ -415,7 +401,7 @@ object FMain_11011981: TFMain_11011981 Align = alTop TabOrder = 1 object ShowNXrefs: TPanel - Left = 644 + Left = 652 Top = 1 Width = 111 Height = 23 @@ -430,7 +416,7 @@ object FMain_11011981: TFMain_11011981 Left = 646 Top = 25 Width = 110 - Height = 552 + Height = 594 Style = lbOwnerDrawFixed Align = alRight Anchors = [] @@ -439,6 +425,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 16 ParentFont = False TabOrder = 2 OnDblClick = lbXrefsDblClick @@ -456,15 +443,11 @@ object FMain_11011981: TFMain_11011981 Font.Style = [] ImageIndex = 5 ParentFont = False - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object lbSourceCode: TListBox Left = 0 Top = 0 Width = 756 - Height = 589 + Height = 619 Align = alClient Font.Charset = RUSSIAN_CHARSET Font.Color = clWindowText @@ -486,22 +469,19 @@ object FMain_11011981: TFMain_11011981 Left = 0 Top = 0 Width = 250 - Height = 605 + Height = 647 ActivePage = tsRTTIs Align = alLeft + TabIndex = 1 TabOrder = 0 OnChange = pcInfoChange object tsUnits: TTabSheet Caption = 'Units (F2)' - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object lbUnits: TListBox Left = 0 Top = 0 Width = 242 - Height = 597 + Height = 619 Style = lbOwnerDrawFixed AutoComplete = False Align = alClient @@ -512,6 +492,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 16 ParentFont = False ParentShowHint = False PopupMenu = pmUnits @@ -519,7 +500,7 @@ object FMain_11011981: TFMain_11011981 TabOrder = 0 OnClick = lbUnitsClick OnDblClick = lbUnitsDblClick - OnDrawItem = lbUnitsDrawItem + OnDrawItem = lbUnitItemsDrawItem OnKeyDown = lbUnitsKeyDown OnMouseMove = lbUnitsMouseMove end @@ -531,7 +512,7 @@ object FMain_11011981: TFMain_11011981 Left = 0 Top = 0 Width = 242 - Height = 577 + Height = 619 AutoComplete = False Align = alClient Color = clWhite @@ -553,13 +534,9 @@ object FMain_11011981: TFMain_11011981 object tsForms: TTabSheet Caption = 'Forms (F5)' ImageIndex = 3 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object Splitter1: TSplitter Left = 0 - Top = 423 + Top = 445 Width = 242 Height = 4 Cursor = crVSplit @@ -567,7 +544,6 @@ object FMain_11011981: TFMain_11011981 Color = clGray MinSize = 3 ParentColor = False - ExplicitTop = 503 end object Panel2: TPanel Left = 0 @@ -596,7 +572,7 @@ object FMain_11011981: TFMain_11011981 Left = 0 Top = 40 Width = 242 - Height = 383 + Height = 405 AutoComplete = False Align = alClient Color = clWhite @@ -617,12 +593,11 @@ object FMain_11011981: TFMain_11011981 end object Panel4: TPanel Left = 0 - Top = 407 + Top = 449 Width = 242 Height = 170 Align = alBottom TabOrder = 2 - ExplicitTop = 427 object lbAliases: TListBox Left = 1 Top = 1 @@ -673,6 +648,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 0 ParentFont = False Sorted = True TabOrder = 0 @@ -703,7 +679,7 @@ object FMain_11011981: TFMain_11011981 end object lbUnitItems: TListBox Left = 0 - Top = 609 + Top = 651 Width = 1017 Height = 146 TabStop = False @@ -717,6 +693,7 @@ object FMain_11011981: TFMain_11011981 Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] + ItemHeight = 16 ParentFont = False PopupMenu = pmUnitItems TabOrder = 2 @@ -728,8 +705,8 @@ object FMain_11011981: TFMain_11011981 end object MainMenu: TMainMenu AutoHotkeys = maManual - Left = 640 - Top = 72 + Left = 632 + Top = 96 object miFile: TMenuItem Caption = '&File' object miLoadFile: TMenuItem @@ -919,6 +896,10 @@ object FMain_11011981: TFMain_11011981 Caption = '&IDC Generator' OnClick = miIDCGeneratorClick end + object miHiewGenerator: TMenuItem + Caption = 'HIEW Generator' + OnClick = miHiewGeneratorClick + end object miLister: TMenuItem Caption = 'Lister' OnClick = miListerClick @@ -939,6 +920,10 @@ object FMain_11011981: TFMain_11011981 Caption = '&Hex->Double' OnClick = miHex2DoubleClick end + object mCreateCHeaderFile: TMenuItem + Caption = 'Create C header file' + OnClick = mCreateCHeaderFileClick + end end object miTabs: TMenuItem Caption = '&Tabs' @@ -1017,12 +1002,16 @@ object FMain_11011981: TFMain_11011981 Action = acFontAll Caption = 'Fonts' end + object mniShellIntegration1: TMenuItem + Caption = 'Shell Integration' + OnClick = mniShellIntegration1Click + end end end end object OpenDlg: TOpenDialog - Left = 688 - Top = 72 + Left = 696 + Top = 96 end object pmCode: TPopupMenu AutoHotkeys = maManual @@ -1054,19 +1043,25 @@ object FMain_11011981: TFMain_11011981 Enabled = False OnClick = miEditFunctionCClick end + object mniN3: TMenuItem + Caption = '-' + end + object miCopyAddressCode: TMenuItem + Caption = 'Copy Address' + OnClick = miCopyAddressCodeClick + end object miCopyCode: TMenuItem Caption = 'Copy to Clipboard' OnClick = miCopyCodeClick end + object mniN4: TMenuItem + Caption = '-' + end object miFuzzyScanKB: TMenuItem Caption = 'Fuzzy scan KB' Enabled = False OnClick = miFuzzyScanKBClick end - object miCopyAddressCode: TMenuItem - Caption = 'Copy Address' - OnClick = miCopyAddressCodeClick - end object miXRefs: TMenuItem Caption = 'XRefs' Enabled = False @@ -1089,8 +1084,8 @@ object FMain_11011981: TFMain_11011981 end end object SaveDlg: TSaveDialog - Left = 632 - Top = 120 + Left = 736 + Top = 96 end object pmUnits: TPopupMenu AutoHotkeys = maManual @@ -1217,8 +1212,8 @@ object FMain_11011981: TFMain_11011981 object pmUnitItems: TPopupMenu AutoHotkeys = maManual OnPopup = pmUnitItemsPopup - Left = 560 - Top = 104 + Left = 544 + Top = 96 object miSearchItem: TMenuItem Caption = 'Search Item' Enabled = False @@ -1249,24 +1244,20 @@ object FMain_11011981: TFMain_11011981 Caption = 'Search' OnClick = miSearchStringClick end - object miCopyStrings: TMenuItem - Caption = 'Copy To Clipboard' - OnClick = miCopyStringsClick - end end object pmCodePanel: TPopupMenu AutoHotkeys = maManual OnPopup = pmCodePanelPopup - Left = 672 - Top = 120 + Left = 664 + Top = 96 object miEmptyHistory: TMenuItem Caption = 'Empty History' OnClick = miEmptyHistoryClick end end object alMain: TActionList - Left = 736 - Top = 72 + Left = 816 + Top = 96 object acOnTop: TAction Category = 'Appearance' Caption = 'Always on top' @@ -1303,12 +1294,14 @@ object FMain_11011981: TFMain_11011981 Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] - Left = 712 - Top = 112 + MinFontSize = 0 + MaxFontSize = 0 + Left = 776 + Top = 96 end object pmSourceCode: TPopupMenu OnPopup = pmSourceCodePopup - Left = 464 + Left = 504 Top = 96 object miCopySource2Clipboard: TMenuItem Caption = 'Copy to Clipboard' @@ -1319,4 +1312,12 @@ object FMain_11011981: TFMain_11011981 OnClick = miSetlvartypeClick end end + object pmNames: TPopupMenu + Left = 464 + Top = 96 + object miCopytoClipboardNames: TMenuItem + Caption = 'Copy to Clipboard' + OnClick = miCopytoClipboardNamesClick + end + end end diff --git a/Main.h b/Main.h new file mode 100644 index 0000000..5d69100 --- /dev/null +++ b/Main.h @@ -0,0 +1,914 @@ +//--------------------------------------------------------------------------- +#ifndef MainH +#define MainH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Disasm.h" +#include "KnowledgeBase.h" +#include "Resources.h" +#include "Infos.h" +#include "UFileDropper.h" +#include +#include "TntStdCtrls.hpp" +//--------------------------------------------------------------------------- +#define USER_KNOWLEDGEBASE 0x80000000 +#define SOURCE_LIBRARY 0x40000000 +#define WM_UPDANALYSISSTATUS WM_USER + 100 +#define WM_DFMCLOSED WM_USER + 101 +#define DELHPI_VERSION_AUTO 0 +//--------------------------------------------------------------------------- +//Internal unit types +#define drStop 0 +#define drStop_a 0x61 //'a' - Last Tag in all files +#define drStop1 0x63 //'c' +#define drUnit 0x64 //'d' +#define drUnit1 0x65 //'e' - in implementation +#define drImpType 0x66 //'f' +#define drImpVal 0x67 //'g' +#define drDLL 0x68 //'h' +#define drExport 0x69 //'i' +#define drEmbeddedProcStart 0x6A //'j' +#define drEmbeddedProcEnd 0x6B //'k' +#define drCBlock 0x6C //'l' +#define drFixUp 0x6D //'m' +#define drImpTypeDef 0x6E //'n' - import of type definition by "A = type B" +#define drUnit2 0x6F //'o' - ??? for D2010 +#define drSrc 0x70 //'p' +#define drObj 0x71 //'q' +#define drRes 0x72 //'r' +#define drAsm 0x73 //'s' - Found in D5 Debug versions +#define drStop2 0x9F //'_' +#define drConst 0x25 //'%' +#define drResStr 0x32 //'2' +#define drType 0x2A //'*' +#define drTypeP 0x26 //'&' +#define drProc 0x28 //'(' +#define drSysProc 0x29 //')' +#define drVoid 0x40 //'@' +#define drVar 0x20 //' ' +#define drThreadVar 0x31 //'1' +#define drVarC 0x27 //''' +#define drBoolRangeDef 0x41 //'A' +#define drChRangeDef 0x42 //'B' +#define drEnumDef 0x43 //'C' +#define drRangeDef 0x44 //'D' +#define drPtrDef 0x45 //'E' +#define drClassDef 0x46 //'F' +#define drObjVMTDef 0x47 //'G' +#define drProcTypeDef 0x48 //'H' +#define drFloatDef 0x49 //'I' +#define drSetDef 0x4A //'J' +#define drShortStrDef 0x4B //'K' +#define drArrayDef 0x4C //'L' +#define drRecDef 0x4D //'M' +#define drObjDef 0x4E //'N' +#define drFileDef 0x4F //'O' +#define drTextDef 0x50 //'P' +#define drWCharRangeDef 0x51 //'Q' - WideChar +#define drStringDef 0x52 //'R' +#define drVariantDef 0x53 //'S' +#define drInterfaceDef 0x54 //'T' +#define drWideStrDef 0x55 //'U' +#define drWideRangeDef 0x56 //'V' +//--------------------------------------------------------------------------- +typedef struct +{ + DWORD Start; + DWORD Size; + DWORD Flags; + String Name; +} SegmentInfo, *PSegmentInfo; + +typedef struct +{ + int caseno; + int count; +} CaseInfo, *PCaseInfo; + +#define cfUndef 0x00000000 +#define cfCode 0x00000001 +#define cfData 0x00000002 +#define cfImport 0x00000004 +#define cfCall 0x00000008 +#define cfProcStart 0x00000010 +#define cfProcEnd 0x00000020 +#define cfRTTI 0x00000040 +#define cfEmbedded 0x00000080 //Calls in range of one proc (for ex. calls in FormatBuf) +#define cfPass0 0x00000100 //Initial Analyze was done +#define cfFrame 0x00000200 +#define cfSwitch 0x00000400 +#define cfPass1 0x00000800 //Analyze1 was done +#define cfETable 0x00001000 //Exception Table +#define cfPush 0x00002000 +#define cfDSkip 0x00004000 //For Decompiler +#define cfPop 0x00008000 +#define cfSetA 0x00010000 //eax setting +#define cfSetD 0x00020000 //edx setting +#define cfSetC 0x00040000 //ecx setting +#define cfBracket 0x00080000 //Bracket (ariphmetic operation) +#define cfPass2 0x00100000 //Analyze2 was done +#define cfExport 0x00200000 +#define cfPass 0x00400000 //Pass Flag (for AnalyzeArguments and Decompiler) +#define cfLoc 0x00800000 //Loc_ position +#define cfTry 0x01000000 +#define cfFinally 0x02000000 +#define cfExcept 0x04000000 +#define cfLoop 0x08000000 +#define cfFinallyExit 0x10000000 //Exit section (from try...finally construction) +#define cfVTable 0x20000000 //Flags for Interface entries (to mark start end finish of VTables) +#define cfSkip 0x40000000 +#define cfInstruction 0x80000000 //Instruction begin + +typedef struct +{ + String name; + DWORD codeOfs; + int codeLen; +} FuncListRec, *PFuncListRec; + +typedef struct UnitRec +{ + ~UnitRec(){delete names;} + bool trivial; //Trivial unit + bool trivialIni; //Initialization procedure is trivial + bool trivialFin; //Finalization procedure is trivial + bool kb; //Unit is in knowledge base + int fromAdr; //From Address + int toAdr; //To Address + int finadr; //Finalization procedure address + int finSize; //Finalization procedure size + int iniadr; //Initialization procedure address + int iniSize; //Initialization procedure size + float matchedPercent; //Matching procent of code in unit + int iniOrder; //Initialization procs order + TStringList *names; //Possible names list +} UnitRec, *PUnitRec; + +typedef struct +{ + BYTE kind; + DWORD adr; + String name; +} TypeRec, *PTypeRec; + +typedef struct +{ + int height; + DWORD vmtAdr; + String vmtName; +} VmtListRec, *PVmtListRec; + +//Delphi2 +//(tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, +//tkClass, tkMethod, tkWChar, tkLString, tkLWString, tkVariant) + +#define ikUnknown 0x00 //UserDefined! +#define ikInteger 0x01 +#define ikChar 0x02 +#define ikEnumeration 0x03 +#define ikFloat 0x04 +#define ikString 0x05 //ShortString +#define ikSet 0x06 +#define ikClass 0x07 +#define ikMethod 0x08 +#define ikWChar 0x09 +#define ikLString 0x0A //String, AnsiString +#define ikWString 0x0B //WideString +#define ikVariant 0x0C +#define ikArray 0x0D +#define ikRecord 0x0E +#define ikInterface 0x0F +#define ikInt64 0x10 +#define ikDynArray 0x11 +//>=2009 +#define ikUString 0x12 //UnicodeString +//>=2010 +#define ikClassRef 0x13 +#define ikPointer 0x14 +#define ikProcedure 0x15 + +//Äîïîëíèòåëüíûå òèïû +#define ikCString 0x20 //PChar, PAnsiChar +#define ikWCString 0x21 //PWideChar + +#define ikResString 0x22 +#define ikVMT 0x23 //VMT +#define ikGUID 0x24 +#define ikRefine 0x25 //Code, but what - procedure or function? +#define ikConstructor 0x26 +#define ikDestructor 0x27 +#define ikProc 0x28 +#define ikFunc 0x29 + +#define ikLoc 0x2A +#define ikData 0x2B +#define ikDataLink 0x2C //Link to variable from other module +#define ikExceptName 0x2D +#define ikExceptHandler 0x2E +#define ikExceptCase 0x2F +#define ikSwitch 0x30 +#define ikCase 0x31 +#define ikFixup 0x32 //Fixup (for example, TlsLast) +#define ikThreadVar 0x33 +#define ikTry 0x34 //!!!Deleted - old format!!! + +enum NameVersion {nvPrimary, nvAfterScan, nvByUser}; +//XRef Type +#define XREF_UNKNOWN 0x20 //Black +#define XREF_CALL 1 //Blue +#define XREF_JUMP 2 //Green +#define XREF_CONST 3 //Light red + +typedef struct +{ + String name; + DWORD address; + WORD ord; +} ExportNameRec, *PExportNameRec; + +typedef struct +{ + String module; + String name; + DWORD address; +} ImportNameRec, *PImportNameRec; + +enum OrdType {OtSByte, OtUByte, OtSWord, OtUWord, OtSLong, OtULong}; + +enum FloatType {FtSingle, FtDouble, FtExtended, FtComp, FtCurr}; + +enum MethodKind {MkProcedure, MkFunction, MkConstructor, MkDestructor, +MkClassProcedure, MkClassFunction}; + +#define PfVar 0x1 +#define PfConst 0x2 +#define PfArray 0x4 +#define PfAddress 0x8 +#define PfReference 0x10 +#define PfOut 0x20 + +enum IntfFlag {IfHasGuid, IfDispInterface, IfDispatch}; + +//Proc navigation history record +typedef struct +{ + DWORD adr; //Procedure Address + int itemIdx; //Selected Item Index + int xrefIdx; //Selected Xref Index + int topIdx; //TopIndex of ListBox +} PROCHISTORYREC, *PPROCHISTORYREC; +//--------------------------------------------------------------------------- +//Information about registry +typedef struct +{ + BYTE result; //0 - nothing, 1 - type was set, 2 - type mismatch + char source; //0 - not defined; 'L' - local var; 'A' - argument; 'M' - memory; 'I' - immediate + DWORD value; + String type; +} RINFO, *PRINFO; +//--------------------------------------------------------------------------- +typedef struct +{ + char* name; + DWORD impAdr; +} SysProcInfo; +//--------------------------------------------------------------------------- +//Common +#define MAXLEN 100 +#define MAXLINE 1024 +#define MAXNAME 1024 +#define MAXSTRBUFFER 10000 +#define MAXBINTEMPLATE 1000 +#define MAX_DISASSEMBLE 250000 +#define MAX_ITEMS 0x10000 //Max items number for read-write +#define HISTORY_CHUNK_LENGTH 256 +//Search +#define SEARCH_UNITS 0 +#define SEARCH_UNITITEMS 1 +#define SEARCH_RTTIS 2 +#define SEARCH_CLASSVIEWER 3 +#define SEARCH_STRINGS 4 +#define SEARCH_FORMS 5 +#define SEARCH_CODEVIEWER 6 +#define SEARCH_NAMES 7 +#define SEARCH_SOURCEVIEWER 8 + +int DISX86Create(); +void DISX86Destroy(); +//--------------------------------------------------------------------------- +template +void CleanupList(TList* list) +{ + if (list) + { + for (int i = 0; i < list->Count; ++i) + { + T* item = (T*)list->Items[i]; + delete item; + } + + delete list; + } +} +//--------------------------------------------------------------------------- +class TDfm; + +class TFMain_11011981 : public TForm +{ +__published: // IDE-managed Components + TMenuItem *miFile; + TMenuItem *miLoadFile; + TMenuItem *miExit; + TMenuItem *miSaveProject; + TOpenDialog *OpenDlg; + TMainMenu *MainMenu; + TMenuItem *miTools; + TPageControl *pcInfo; + TTabSheet *tsUnits; + TTabSheet *tsRTTIs; + TListBox *lbUnits; + TListBox *lbRTTIs; + TMenuItem *miOpenProject; + TPageControl *pcWorkArea; + TTabSheet *tsCodeView; + TListBox *lbCode; + TPopupMenu *pmCode; + TMenuItem *miGoTo; + TMenuItem *miExploreAdr; + TSaveDialog *SaveDlg; + TSplitter *SplitterH1; + TSplitter *SplitterV1; + TMenuItem *miViewProto; + TPanel *CodePanel; + TButton *bEP; + TButton *bCodePrev; + TTabSheet *tsClassView; + TTreeView *tvClassesFull; + TTabSheet *tsStrings; + TTntListBox *lbStrings; + TPanel *Panel1; + TPopupMenu *pmUnits; + TMenuItem *miSearchUnit; + TMenuItem *miSortUnits; + TMenuItem *miSortUnitsByAdr; + TMenuItem *miSortUnitsByOrd; + TPopupMenu *pmRTTIs; + TPopupMenu *pmVMTs; + TMenuItem *miSearchRTTI; + TMenuItem *miSortRTTI; + TMenuItem *miSortRTTIsByAdr; + TMenuItem *miSortRTTIsByKnd; + TMenuItem *miSortRTTIsByNam; + TMenuItem *miSearchVMT; + TMenuItem *miCopyCode; + TMenuItem *miRenameUnit; + TPopupMenu *pmUnitItems; + TMenuItem *miSearchItem; + TTabSheet *tsForms; + TPanel *Panel2; + TRadioGroup *rgViewFormAs; + TListBox *lbForms; + TMenuItem *miCollapseAll; + TListBox *lbCXrefs; + TPanel *ShowCXrefs; + TMenuItem *miSortUnitsByNam; + TTreeView *tvClassesShort; + TRadioGroup *rgViewerMode; + TMenuItem *miClassTreeBuilder; + TMenuItem *miMRF; + TMenuItem *miExe1; + TMenuItem *miExe2; + TMenuItem *miExe3; + TMenuItem *miExe4; + TMenuItem *miIdp1; + TMenuItem *miIdp2; + TMenuItem *miIdp3; + TMenuItem *miIdp4; + TMenuItem *N1; + TTabSheet *tsItems; + TStringGrid *sgItems; + TMenuItem *miExe5; + TMenuItem *miExe6; + TMenuItem *miExe7; + TMenuItem *miExe8; + TMenuItem *miIdp5; + TMenuItem *miIdp6; + TMenuItem *miIdp7; + TMenuItem *miIdp8; + TListBox *lbUnitItems; + TMenuItem *miEditFunctionC; + TMenuItem *miMapGenerator; + TMenuItem *miAutodetectVersion; + TMenuItem *miDelphi2; + TMenuItem *miDelphi3; + TMenuItem *miDelphi4; + TMenuItem *miDelphi5; + TMenuItem *miDelphi6; + TMenuItem *miDelphi7; + TMenuItem *miDelphi2006; + TMenuItem *miDelphi2007; + TMenuItem *miKBTypeInfo; + TMenuItem *miName; + TMenuItem *miLister; + TButton *bCodeNext; + TLabel *lProcName; + TMenuItem *miInformation; + TMenuItem *miEditFunctionI; + TPopupMenu *pmStrings; + TMenuItem *miSearchString; + TMenuItem *miViewClass; + TMenuItem *miDelphi2009; + TMenuItem *miDelphi2010; + TPanel *Panel3; + TListBox *lbSXrefs; + TPanel *ShowSXrefs; + TMenuItem *miAbout; + TMenuItem *miHelp; + TMenuItem *miEditClass; + TMenuItem *miCtdPassword; + TPopupMenu *pmCodePanel; + TMenuItem *miEmptyHistory; + TMenuItem *miTabs; + TMenuItem *Units1; + TMenuItem *RTTI1; + TMenuItem *Forms1; + TMenuItem *CodeViewer1; + TMenuItem *ClassViewer1; + TMenuItem *Strings1; + TMenuItem *miUnitDumper; + TTabSheet *tsNames; + TMenuItem *Names1; + TListBox *lbNames; + TPanel *Panel4; + TSplitter *Splitter1; + TListBox *lbAliases; + TPanel *pnlAliases; + TLabel *lClassName; + TComboBox *cbAliases; + TButton *bApplyAlias; + TButton *bCancelAlias; + TMenuItem *miLegend; + TMenuItem *miFuzzyScanKB; + TMenuItem *miCopyList; + TMenuItem *miDelphi2005; + TMenuItem *miCommentsGenerator; + TMenuItem *miIDCGenerator; + TMenuItem *miSaveDelphiProject; + TTabSheet *tsSourceCode; + TListBox *lbSourceCode; + TMenuItem *SourceCode1; + TPanel *Panel5; + TPanel *ShowNXrefs; + TListBox *lbNXrefs; + TMenuItem *miHex2Double; + TActionList *alMain; + TAction *acOnTop; + TAction *acShowBar; + TAction *acShowHoriz; + TAction *acDefCol; + TAction *acColorThis; + TAction *acFontAll; + TAction *acColorAll; + TFontDialog *FontsDlg; + TMenuItem *Appearance2; + TMenuItem *Colorsall2; + TMenuItem *Colorsthis2; + TMenuItem *Fontall2; + TMenuItem *Fontthis2; + TMenuItem *Defaultcolumns2; + TMenuItem *Showhorizontalscroll2; + TMenuItem *Showbar2; + TButton *bDecompile; + TMenuItem *miCopyAddressI; + TMenuItem *miCopyAddressCode; + TPopupMenu *pmSourceCode; + TMenuItem *miCopySource2Clipboard; + TMenuItem *miDelphiXE1; + TMenuItem *miXRefs; + TMenuItem *miDelphiXE2; + TMenuItem *miPlugins; + TMenuItem *miViewAll; + TCheckBox *cbMultipleSelection; + TMenuItem *miSwitchSkipFlag; + TMenuItem *miSwitchFrameFlag; + TMenuItem *miSwitchFlag; + TMenuItem *cfTry1; + TMenuItem *miDelphiXE3; + TMenuItem *miSettings; + TMenuItem *miacFontAll; + TMenuItem *miDelphiXE4; + TMenuItem *miProcessDumper; + TMenuItem *miSetlvartype; + TPopupMenu *pmNames; + TMenuItem *miCopytoClipboardNames; + TMenuItem *miHiewGenerator; + TMenuItem *mniShellIntegration1; + TMenuItem *mniN3; + TMenuItem *mniN4; + TMenuItem *mCreateCHeaderFile; + void __fastcall miExitClick(TObject *Sender); + void __fastcall miAutodetectVersionClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall miSaveProjectClick(TObject *Sender); + void __fastcall miOpenProjectClick(TObject *Sender); + void __fastcall lbCodeDblClick(TObject *Sender); + void __fastcall bEPClick(TObject *Sender); + void __fastcall lbStringsDblClick(TObject *Sender); + void __fastcall lbRTTIsDblClick(TObject *Sender); + void __fastcall lbUnitItemsDblClick(TObject *Sender); + void __fastcall lbUnitsDblClick(TObject *Sender); + void __fastcall miGoToClick(TObject *Sender); + void __fastcall miExploreAdrClick(TObject *Sender); + void __fastcall miNameClick(TObject *Sender); + void __fastcall miViewProtoClick(TObject *Sender); + void __fastcall lbXrefsDblClick(TObject *Sender); + void __fastcall bCodePrevClick(TObject *Sender); + void __fastcall tvClassesDblClick(TObject *Sender); + void __fastcall miSearchUnitClick(TObject *Sender); + void __fastcall miSortUnitsByAdrClick(TObject *Sender); + void __fastcall miSortUnitsByOrdClick(TObject *Sender); + void __fastcall miSearchVMTClick(TObject *Sender); + void __fastcall miSearchRTTIClick(TObject *Sender); + void __fastcall miSortRTTIsByAdrClick(TObject *Sender); + void __fastcall miSortRTTIsByKndClick(TObject *Sender); + void __fastcall miSortRTTIsByNamClick(TObject *Sender); + void __fastcall miCopyCodeClick(TObject *Sender); + void __fastcall miRenameUnitClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall lbFormsDblClick(TObject *Sender); + void __fastcall lbUnitsDrawItem(TWinControl *Control, + int Index, TRect &Rect, TOwnerDrawState State); + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall lbCodeKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall miCollapseAllClick(TObject *Sender); + void __fastcall NamePosition(); + void __fastcall GoToAddress(); + void __fastcall FindText(String Str); + void __fastcall miSearchItemClick(TObject *Sender); + void __fastcall ShowCXrefsClick(TObject *Sender); + void __fastcall lbUnitItemsDrawItem(TWinControl *Control, + int Index, TRect &Rect, TOwnerDrawState State); + void __fastcall lbUnitsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall lbRTTIsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall lbFormsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall lbCodeMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall tvClassesFullMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall lbStringsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall lbUnitItemsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall lbXrefsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall miSortUnitsByNamClick(TObject *Sender); + void __fastcall rgViewerModeClick(TObject *Sender); + void __fastcall tvClassesShortMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall miClassTreeBuilderClick(TObject *Sender); + void __fastcall lbUnitsClick(TObject *Sender); + void __fastcall lbRTTIsClick(TObject *Sender); + void __fastcall lbUnitItemsClick(TObject *Sender); + void __fastcall tvClassesShortClick(TObject *Sender); + void __fastcall tvClassesFullClick(TObject *Sender); + void __fastcall miExe1Click(TObject *Sender); + void __fastcall miExe2Click(TObject *Sender); + void __fastcall miExe3Click(TObject *Sender); + void __fastcall miExe4Click(TObject *Sender); + void __fastcall miIdp1Click(TObject *Sender); + void __fastcall miIdp2Click(TObject *Sender); + void __fastcall miIdp3Click(TObject *Sender); + void __fastcall miIdp4Click(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall miKBTypeInfoClick(TObject *Sender); + void __fastcall miExe5Click(TObject *Sender); + void __fastcall miExe6Click(TObject *Sender); + void __fastcall miExe7Click(TObject *Sender); + void __fastcall miExe8Click(TObject *Sender); + void __fastcall miIdp5Click(TObject *Sender); + void __fastcall miIdp6Click(TObject *Sender); + void __fastcall miIdp7Click(TObject *Sender); + void __fastcall miIdp8Click(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall miEditFunctionCClick(TObject *Sender); + void __fastcall lbXrefsDrawItem(TWinControl *Control, int Index, + TRect &Rect, TOwnerDrawState State); + void __fastcall miMapGeneratorClick(TObject *Sender); + void __fastcall pmUnitsPopup(TObject *Sender); + void __fastcall lbCodeDrawItem(TWinControl *Control, int Index, + TRect &Rect, TOwnerDrawState State); + void __fastcall miDelphi2Click(TObject *Sender); + void __fastcall miDelphi3Click(TObject *Sender); + void __fastcall miDelphi4Click(TObject *Sender); + void __fastcall miDelphi5Click(TObject *Sender); + void __fastcall miDelphi6Click(TObject *Sender); + void __fastcall miDelphi7Click(TObject *Sender); + void __fastcall miDelphi2005Click(TObject *Sender); + void __fastcall miDelphi2006Click(TObject *Sender); + void __fastcall miDelphi2007Click(TObject *Sender); + void __fastcall lbXrefsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall lbUnitsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall lbRTTIsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall lbFormsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall tvClassesShortKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall lbUnitItemsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall miListerClick(TObject *Sender); + void __fastcall bCodeNextClick(TObject *Sender); + void __fastcall miEditFunctionIClick(TObject *Sender); + void __fastcall miSearchStringClick(TObject *Sender); + void __fastcall lbStringsClick(TObject *Sender); + void __fastcall miViewClassClick(TObject *Sender); + void __fastcall pmVMTsPopup(TObject *Sender); + //void __fastcall lbStringsDrawItem(TWinControl *Control, int Index, + // TRect &Rect, TOwnerDrawState State); + void __fastcall ShowSXrefsClick(TObject *Sender); + void __fastcall miAboutClick(TObject *Sender); + void __fastcall miHelpClick(TObject *Sender); + void __fastcall pmRTTIsPopup(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall miEditClassClick(TObject *Sender); + void __fastcall miCtdPasswordClick(TObject *Sender); + void __fastcall pmCodePanelPopup(TObject *Sender); + void __fastcall miEmptyHistoryClick(TObject *Sender); + void __fastcall pmStringsPopup(TObject *Sender); + void __fastcall Units1Click(TObject *Sender); + void __fastcall RTTI1Click(TObject *Sender); + void __fastcall Forms1Click(TObject *Sender); + void __fastcall CodeViewer1Click(TObject *Sender); + void __fastcall ClassViewer1Click(TObject *Sender); + void __fastcall Strings1Click(TObject *Sender); + void __fastcall Names1Click(TObject *Sender); + void __fastcall miUnitDumperClick(TObject *Sender); + void __fastcall miFuzzyScanKBClick(TObject *Sender); + void __fastcall miDelphi2009Click(TObject *Sender); + void __fastcall miDelphi2010Click(TObject *Sender); + void __fastcall lbNamesClick(TObject *Sender); + void __fastcall bApplyAliasClick(TObject *Sender); + void __fastcall bCancelAliasClick(TObject *Sender); + void __fastcall lbAliasesDblClick(TObject *Sender); + void __fastcall miLegendClick(TObject *Sender); + void __fastcall miCopyListClick(TObject *Sender); + void __fastcall miCommentsGeneratorClick(TObject *Sender); + void __fastcall miIDCGeneratorClick(TObject *Sender); + void __fastcall miSaveDelphiProjectClick(TObject *Sender); + void __fastcall bDecompileClick(TObject *Sender); + void __fastcall SourceCode1Click(TObject *Sender); + void __fastcall miHex2DoubleClick(TObject *Sender); + void __fastcall acFontAllExecute(TObject *Sender); + void __fastcall pmUnitItemsPopup(TObject *Sender); + void __fastcall miCopyAddressIClick(TObject *Sender); + void __fastcall miCopyAddressCodeClick(TObject *Sender); + void __fastcall miCopySource2ClipboardClick(TObject *Sender); + void __fastcall miDelphiXE1Click(TObject *Sender); + void __fastcall pmCodePopup(TObject *Sender); + void __fastcall lbFormsClick(TObject *Sender); + void __fastcall lbCodeClick(TObject *Sender); + void __fastcall pcInfoChange(TObject *Sender); + void __fastcall pcWorkAreaChange(TObject *Sender); + void __fastcall miDelphiXE2Click(TObject *Sender); + void __fastcall miPluginsClick(TObject *Sender); + void __fastcall miCopyStringsClick(TObject *Sender); + void __fastcall miViewAllClick(TObject *Sender); + void __fastcall lbSourceCodeMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y); + void __fastcall cbMultipleSelectionClick(TObject *Sender); + void __fastcall lbSourceCodeDrawItem(TWinControl *Control, int Index, + TRect &Rect, TOwnerDrawState State); + void __fastcall miSwitchSkipFlagClick(TObject *Sender); + void __fastcall miSwitchFrameFlagClick(TObject *Sender); + void __fastcall cfTry1Click(TObject *Sender); + void __fastcall miDelphiXE3Click(TObject *Sender); + void __fastcall miDelphiXE4Click(TObject *Sender); + void __fastcall miProcessDumperClick(TObject *Sender); + void __fastcall lbSourceCodeClick(TObject *Sender); + void __fastcall miSetlvartypeClick(TObject *Sender); + void __fastcall pmSourceCodePopup(TObject *Sender); + void __fastcall miCopytoClipboardNamesClick(TObject *Sender); + void __fastcall miHiewGeneratorClick(TObject *Sender); + void __fastcall mniShellIntegration1Click(TObject *Sender); + void __fastcall mCreateCHeaderFileClick(TObject *Sender); + void __fastcall OutputForwardDeclarationsHeader(FILE* hF); + void __fastcall OutputForwardDeclarationsOfKind(FILE* hF, BYTE kind); + void __fastcall CreateCppHeaderFile(FILE* hF); + //void __fastcall mniMap1Click(TObject *Sender); + //void __fastcall mniCopyAllToClipboardClick(TObject *Sender); + //void __fastcall lstMapDblClick(TObject *Sender); + //void __fastcall mniCopyLinesClick(TObject *Sender); + //void __fastcall mniCopyLinesStrings1Click(TObject *Sender); +private: // User declarations + bool ProjectLoaded; + + void __fastcall Init(); + void __fastcall AnalyzeThreadDone(TObject* Sender); + + bool __fastcall IsExe(String FileName); + bool __fastcall IsIdp(String FileName); + void __fastcall LoadFile(String FileName, int version); + void __fastcall LoadDelphiFile(int version); + void __fastcall LoadDelphiFile1(String FileName, int version, bool loadExp, bool loadImp); + void __fastcall ReadNode(FILE* fIn, TTreeNode* node, char* buf); + //void __fastcall ReadNode(TStream* stream, TTreeNode* node, char* buf); + void __fastcall OpenProject(String FileName); + bool __fastcall ImportsValid(DWORD ImpRVA, DWORD ImpSize); + int __fastcall LoadImage(FILE* f, int version, bool loadExp, bool loadImp); + void __fastcall FindExports(); + void __fastcall FindImports(); + int __fastcall GetDelphiVersion(); + void __fastcall InitSysProcs(); + bool __fastcall IsExtendedInitTab(DWORD* unitsTab); + int __fastcall GetUnits2(String dprName); //For Delphi2 (other structure!) + int __fastcall GetUnits(String dprName); + int __fastcall GetBCBUnits(String dprName); + int __fastcall IsValidCode(DWORD fromAdr); + void __fastcall CodeHistoryPush(PPROCHISTORYREC rec); + PPROCHISTORYREC __fastcall CodeHistoryPop(); + void __fastcall ShowCodeXrefs(DWORD Adr, int selIdx); + void __fastcall ShowStringXrefs(DWORD Adr, int selIdx); + void __fastcall ShowNameXrefs(DWORD Adr, int selIdx); + void __fastcall WriteNode(FILE* f, TTreeNode* node);//void __fastcall WriteNode(TStream* stream, TTreeNode* node); + void __fastcall SaveProject(String FileName); + void __fastcall CloseProject(); + void __fastcall CleanProject(); + void __fastcall IniFileRead(); + void __fastcall IniFileWrite(); + void __fastcall AddExe2MRF(String FileName); + void __fastcall AddIdp2MRF(String FileName); + int __fastcall GetSegmentNo(DWORD Adr); + int __fastcall CodeGetTargetAdr(String line, DWORD* trgAdr); + void __fastcall OutputLine(FILE* outF, BYTE flags, DWORD adr, String content); + void __fastcall OutputCode(FILE* outF, DWORD fromAdr, String prototype, bool onlyComments); + //Drag&Drop + TDragDropHelper dragdropHelper; + void __fastcall wm_dropFiles(TWMDropFiles& msg); + void __fastcall DoOpenProjectFile(String FileName); + bool __fastcall ContainsUnexplored(PUnitRec recU); + //GUI update from thread + void __fastcall wm_updAnalysisStatus(TMessage& msg); + void __fastcall wm_dfmClosed(TMessage& msg); + //Tree view booster + typedef std::map TTreeNodeNameMap; + TTreeNodeNameMap tvClassMap; + void __fastcall ClearTreeNodeMap(); + + void __fastcall SetupAllFonts(TFont* font); + + void __fastcall miSearchFormClick(TObject *Sender); + void __fastcall miSearchNameClick(TObject *Sender); + +public: // User declarations + String AppDir; + String WrkDir; + String SourceFile; + int SysProcsNum; //Number of elements in SysProcs array + + int WhereSearch; + //UNITS + int UnitsSearchFrom; + TStringList *UnitsSearchList; + String UnitsSearchText; + //RTTIS + int RTTIsSearchFrom; + TStringList *RTTIsSearchList; + String RTTIsSearchText; + //UNITITEMS + int UnitItemsSearchFrom; + TStringList *UnitItemsSearchList; + String UnitItemsSearchText; + //FORMS + int FormsSearchFrom; + TStringList *FormsSearchList; + String FormsSearchText; + //VMTS + TTreeNode *TreeSearchFrom; + TTreeNode *BranchSearchFrom; + TStringList *VMTsSearchList; + String VMTsSearchText; + //STRINGS + int StringsSearchFrom; + TStringList *StringsSearchList; + String StringsSearchText; + //NAMES + int NamesSearchFrom; + TStringList *NamesSearchList; + String NamesSearchText; + + __fastcall TFMain_11011981(TComponent* Owner); + __fastcall ~TFMain_11011981(); + + void __fastcall DoOpenDelphiFile(int version, String FileName, bool loadExp, bool loadImp); + void __fastcall ClearPassFlags(); + DWORD __fastcall FollowInstructions(DWORD fromAdr, DWORD toAdr); + int __fastcall EstimateProcSize(DWORD fromAdr); + DWORD __fastcall EvaluateInitTable(BYTE* Data, DWORD Size, DWORD Base); + PFIELDINFO __fastcall GetField(String TypeName, int Offset, bool* vmt, DWORD* vmtAdr, String prefix); + PFIELDINFO __fastcall AddField(DWORD ProcAdr, int ProcOfs, String TypeName, BYTE Scope, int Offset, int Case, String Name, String Type); + int __fastcall GetMethodOfs(PInfoRec rec, DWORD procAdr); + PMethodRec __fastcall GetMethodInfo(PInfoRec rec, String name); + PMethodRec __fastcall GetMethodInfo(DWORD adr, char kind, int methodOfs); + + PImportNameRec __fastcall GetImportRec(DWORD adr); + void __fastcall StrapProc(int pos, int ProcId, MProcInfo* ProcInfo, bool useFixups, int procSize); + void __fastcall ShowUnits(bool showUnk); + void __fastcall ShowUnitItems(PUnitRec recU, int topIdx, int itemIdx); + void __fastcall ShowRTTIs(); + void __fastcall FillVmtList(); + void __fastcall ShowClassViewer(DWORD VmtAdr); + bool __fastcall IsUnitExist(String Name); + void __fastcall SetVmtConsts(int version); + PUnitRec __fastcall GetUnit(DWORD Adr); + String __fastcall GetUnitName(PUnitRec recU); + String __fastcall GetUnitName(DWORD Adr); + void __fastcall SetUnitName(PUnitRec recU, String name); + bool __fastcall InOneUnit(DWORD Adr1, DWORD Adr2); + void __fastcall StrapVMT(int pos, int ConstId, MConstInfo* ConstInfo); + bool __fastcall StrapCheck(int pos, MProcInfo* ProcInfo); + TTreeNode* __fastcall GetNodeByName(String AName); + + void __fastcall ScanIntfTable(DWORD adr); + void __fastcall ScanAutoTable(DWORD adr); + void __fastcall ScanInitTable(DWORD adr); + void __fastcall ScanFieldTable(DWORD adr); + void __fastcall ScanMethodTable(DWORD adr, String className); + void __fastcall ScanDynamicTable(DWORD adr); + void __fastcall ScanVirtualTable(DWORD adr); + int __fastcall GetClassHeight(DWORD adr); + String __fastcall GetCommonType(String Name1, String Name2); + void __fastcall PropagateVMTNames(DWORD adr); + + void __fastcall ShowStrings(int idx); + void __fastcall ShowNames(int idx); + //void __fastcall ScanImports(); + void __fastcall RedrawCode(); + int __fastcall AddAsmLine(DWORD Adr, String text, BYTE Flags); + void __fastcall ShowCode(DWORD fromAdr, int SelectedIdx, int XrefIdx, int topIdx); + void __fastcall AnalyzeProc(int pass, DWORD procAdr); + void __fastcall AnalyzeMethodTable(int pass, DWORD adr, const bool* Terminated); + void __fastcall AnalyzeDynamicTable(int pass, DWORD adr, const bool* Terminated); + void __fastcall AnalyzeVirtualTable(int pass, DWORD adr, const bool* Terminated); + DWORD __fastcall AnalyzeProcInitial(DWORD fromAdr); + void __fastcall AnalyzeProc1(DWORD fromAdr, char xrefType, DWORD xrefAdr, int xrefOfs, bool maybeEmb); + void __fastcall AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType); + bool __fastcall AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType, TList *sctx); + String __fastcall AnalyzeTypes(DWORD parentAdr, int callPos, DWORD procAdr, PRINFO registers); + String __fastcall AnalyzeArguments(DWORD fromAdr); + + int __fastcall LoadIntfTable(DWORD adr, TStringList* dstList); + int __fastcall LoadAutoTable(DWORD adr, TStringList* dstList); + int __fastcall LoadFieldTable(DWORD adr, TList* dstList); + int __fastcall LoadAllFields(DWORD adr, TList* dstList); + int __fastcall LoadMethodTable(DWORD adr, TList* dstList); + int __fastcall LoadMethodTable(DWORD adr, TStringList* dstList); + int __fastcall LoadDynamicTable(DWORD adr, TList* dstList); + int __fastcall LoadDynamicTable(DWORD adr, TStringList* dstList); + int __fastcall LoadVirtualTable(DWORD adr, TList* dstList); + int __fastcall LoadVirtualTable(DWORD adr, TStringList* dstList); + void __fastcall FillClassViewerOne(int n, TStringList* tmpList, const bool* terminated); + TTreeNode* __fastcall AddClassTreeNode(TTreeNode* node, String name); + //Function + void __fastcall EditFunction(DWORD Adr); + String __fastcall MakeComment(PPICODE Picode); + void __fastcall InitAliases(bool find); + void __fastcall CopyAddress(String line, int ofs, int bytes); + void __fastcall GoToXRef(TObject *Sender); + //void __fastcall ChangeDelphiHighlightTheme(TObject *Sender); + + BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, wm_dropFiles); + VCL_MESSAGE_HANDLER(WM_UPDANALYSISSTATUS, TMessage, wm_updAnalysisStatus); + VCL_MESSAGE_HANDLER(WM_DFMCLOSED, TMessage, wm_dfmClosed); + END_MESSAGE_MAP(TForm) + + //Treenode booster for analysis + void __fastcall AddTreeNodeWithName(TTreeNode* node, const String& name); + TTreeNode* __fastcall FindTreeNodeByName(const String& name); + + //show Form by its dfm object + void __fastcall ShowDfm(TDfm* dfm); + //bool __fastcall ImportIdp(String fileName); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFMain_11011981 *FMain_11011981; +//--------------------------------------------------------------------------- +#endif diff --git a/Misc.cpp b/Misc.cpp new file mode 100644 index 0000000..d866818 --- /dev/null +++ b/Misc.cpp @@ -0,0 +1,4590 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Misc.h" +#include +#include "assert.h" +#include "InputDlg.h" +//--------------------------------------------------------------------------- +extern int dummy; +extern String IDRVersion; +extern String SelectedAsmItem; +extern char StringBuf[MAXSTRBUFFER]; +extern DWORD ImageBase; +extern DWORD ImageSize; +extern DWORD TotalSize; +extern DWORD CodeBase; +extern DWORD CodeSize; +extern DWORD DataBase; +extern DWORD *Flags; +extern PInfoRec *Infos; +extern TStringList *BSSInfos; +extern MDisasm Disasm; +extern MKnowledgeBase KnowledgeBase; +extern BYTE *Code; +extern int DelphiVersion; +extern TList *SegmentList; +extern TList *OwnTypeList; +extern TList *VmtList; +extern int cVmtSelfPtr; +extern int cVmtIntfTable; +extern int cVmtInitTable; +extern int cVmtParent; +extern int cVmtClassName; +extern int cVmtInstanceSize; +extern char* Reg8Tab[8]; +extern char* Reg16Tab[8]; +extern char* Reg32Tab[8]; +extern char* SegRegTab[8]; + +//Add by ZGL----------------------------------------------------------------- +WideString __fastcall TUnicodeClipboard::GetAsUnicodeText() +{ + WideString res; + Open(); + HANDLE data = GetClipboardData(CF_UNICODETEXT); + try + { + if (data) + res = (wchar_t *)GlobalLock(data); + else + res = ""; + } + __finally + { + if (data) GlobalUnlock(data); + Close(); + } + return res; +} +//Add by ZGL----------------------------------------------------------------- +void __fastcall TUnicodeClipboard::SetAsUnicodeText(const WideString Value) +{ + SetBuffer(CF_UNICODETEXT, (wchar_t *)Value, (wcslen(Value) + 1) * sizeof(WideChar)); +} +//--------------------------------------------------------------------------- +WideString __fastcall UnicodeEncode(String Str, int CodePage) +{ + int Len; + WideString Result; + + Len = Str.Length() + 1; + Result.SetLength(Len); + Len = MultiByteToWideChar(CodePage, 0, PChar(Str.c_str()), -1, PWideChar(Result), Len); + Result.SetLength(Len - 1); //end is #0 + return Result; +}; +//--------------------------------------------------------------------------- +String __fastcall UnicodeDecode(WideString Str, int CodePage) +{ + int Len; + String Result; + + Len = Str.Length() * 2 + 1; //one for #0 + Result.SetLength(Len); + Len = WideCharToMultiByte(CodePage, 0, PWideChar(Str), -1, PChar(Result.c_str()), Len, 0, 0); + Result.SetLength(Len - 1); + return Result; +}; +//--------------------------------------------------------------------------- +void __fastcall ScaleForm(TForm* AForm) +{ + HDC _hdc = GetDC(0); + if (_hdc) + { + //Modified by ZGL + int LogicalScreenHeight = GetDeviceCaps(_hdc, VERTRES); + int PhysicalScreenHeight = GetDeviceCaps(_hdc, DESKTOPVERTRES); + AForm->ScaleBy(PhysicalScreenHeight, LogicalScreenHeight); + //Modified end + ReleaseDC(0, _hdc); + } +} +//--------------------------------------------------------------------------- +int __fastcall Adr2Pos(DWORD adr) +{ + int ofs = 0; + for (int n = 0; n < SegmentList->Count; n++) + { + PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; + if (segInfo->Start <= adr && adr < segInfo->Start + segInfo->Size) + { + if (segInfo->Flags & 0x80000) + return -1; + return ofs + (adr - segInfo->Start); + } + if (!(segInfo->Flags & 0x80000)) + ofs += segInfo->Size; + } + return -2; +} +//--------------------------------------------------------------------------- +DWORD __fastcall Pos2Adr(int Pos) +{ + int fromPos = 0; + int toPos = 0; + for (int n = 0; n < SegmentList->Count; n++) + { + PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; + if (!(segInfo->Flags & 0x80000)) + { + fromPos = toPos; + toPos += segInfo->Size; + if (fromPos <= Pos && Pos < toPos) + return segInfo->Start + (Pos - fromPos); + } + } + return 0; +} +//--------------------------------------------------------------------------- +//Can replace type "fromName" to type "toName"? +bool __fastcall CanReplace(const String& fromName, const String& toName) +{ + //Skip empty toName + if (toName == "") return false; + //We can replace empty "fromName" or name "byte", "word", "dword' + if (fromName == "" || SameText(fromName, "byte") || SameText(fromName, "word") || SameText(fromName, "dword")) return true; + return false; +} +//--------------------------------------------------------------------------- +String __fastcall GetDefaultProcName(DWORD adr) +{ + return "sub_" + Val2Str8(adr); +} +//--------------------------------------------------------------------------- +String __fastcall Val2Str0(DWORD Val) +{ + return IntToHex((int)Val, 0); +} +//--------------------------------------------------------------------------- +String __fastcall Val2Str1(DWORD Val) +{ + return IntToHex((int)Val, 1); +} +//--------------------------------------------------------------------------- +String __fastcall Val2Str2(DWORD Val) +{ + return IntToHex((int)Val, 2); +} +//--------------------------------------------------------------------------- +String __fastcall Val2Str4(DWORD Val) +{ + return IntToHex((int)Val, 4); +} +//--------------------------------------------------------------------------- +String __fastcall Val2Str5(DWORD Val) +{ + return IntToHex((int)Val, 5); +} +//--------------------------------------------------------------------------- +String __fastcall Val2Str8(DWORD Val) +{ + return IntToHex((int)Val, 8); +} +//--------------------------------------------------------------------------- +PInfoRec __fastcall AddToBSSInfos(DWORD Adr, String AName, String ATypeName) +{ + PInfoRec recN; + String _key = Val2Str8(Adr); + int _idx = BSSInfos->IndexOf(_key); + if (_idx == -1) + { + recN = new InfoRec(-1, ikData); + recN->SetName(AName); + recN->type = ATypeName; + BSSInfos->AddObject(_key, (TObject*)recN); + } + else + { + recN = (PInfoRec)BSSInfos->Objects[_idx]; + if (recN->type == "") + { + recN->type = ATypeName; + } + } + return recN; +} +//--------------------------------------------------------------------------- +String __fastcall MakeGvarName(DWORD adr) +{ + return "gvar_" + Val2Str8(adr); +} +//--------------------------------------------------------------------------- +void __fastcall MakeGvar(PInfoRec recN, DWORD adr, DWORD xrefAdr) +{ + if (!recN->HasName()) recN->SetName(MakeGvarName(adr)); + if (xrefAdr) recN->AddXref('C', xrefAdr, 0); +} +//--------------------------------------------------------------------------- +void __fastcall FillArgInfo(int k, BYTE callkind, PARGINFO argInfo, BYTE** p, int* s) +{ + BYTE* pp = *p; int ss = *s; + argInfo->Tag = *pp; pp++; + int locflags = *((int*)pp); pp += 4; + + if ((locflags & 7) == 1) argInfo->Tag = 0x23; //Add by ZGL + + argInfo->Register = (locflags & 8); + int ndx = *((int*)pp); pp += 4; + + //fastcall + if (!callkind) + { + if (argInfo->Register && k < 3) + { + argInfo->Ndx = k;// << 24;??? + } + else + { + argInfo->Ndx = ndx; + } + } + //stdcall, cdecl, pascal + else + { + argInfo->Ndx = ss; + ss += 4; + } + + argInfo->Size = 4; + WORD wlen = *((WORD*)pp); pp += 2; + argInfo->Name = String((char*)pp, wlen); pp += wlen + 1; + wlen = *((WORD*)pp); pp += 2; + argInfo->TypeDef = TrimTypeName(String((char*)pp, wlen)); pp += wlen + 1; + *p = pp; *s = ss; +} +//--------------------------------------------------------------------------- +String __fastcall TrimTypeName(const String& TypeName) +{ + if (TypeName.IsEmpty()) + return TypeName; + int pos = TypeName.Pos("."); + //No '.' in TypeName or TypeName begins with '.' + if (pos == 0 || pos == 1) + return TypeName; + //èëè ýòî èìÿ òèïà range + else if (TypeName[pos + 1] == '.') + return TypeName; + else + { + char c, *p = TypeName.c_str(); + //Check special symbols upto '.' + while (1) + { + c = *p++; + if (c == '.') break; + if (c < '0' || c == '<') + return TypeName; + } + return ExtractProcName(TypeName); + } +} +//--------------------------------------------------------------------------- +bool __fastcall IsValidImageAdr(DWORD Adr) +{ + if (Adr >> 8 == 0x408D) return false; //Add by ZGL assigned global byte or boolean variable + if (Adr >= CodeBase && Adr < CodeBase + ImageSize) + return true; + else + return false; +} +//--------------------------------------------------------------------------- +bool __fastcall IsValidCodeAdr(DWORD Adr) +{ + if (Adr >= CodeBase && Adr < CodeBase + CodeSize) + return true; + else + return false; +} +//--------------------------------------------------------------------------- +String __fastcall ExtractClassName(const String& AName) +{ + if (AName == "") return ""; + int pos = AName.Pos("."); + if (pos) + return AName.SubString(1, pos - 1); + else + return ""; +} +//--------------------------------------------------------------------------- +String __fastcall ExtractProcName(const String& AName) +{ + if (AName == "") return ""; + int pos = AName.Pos("."); + if (pos) + return AName.SubString(pos + 1, AName.Length()); + else + return AName; +} +//--------------------------------------------------------------------------- +String __fastcall ExtractName(const String& AName) +{ + if (AName == "") return ""; + int _pos = AName.Pos(":"); + if (_pos) + return AName.SubString(1, _pos - 1); + else + return AName; +} +//--------------------------------------------------------------------------- +String __fastcall ExtractType(const String& AName) +{ + if (AName == "") return ""; + int _pos = AName.Pos(":"); + if (_pos) + return AName.SubString(_pos + 1, AName.Length()); + else + return ""; +} +//--------------------------------------------------------------------------- +//Return position of nearest up argument eax from position fromPos +int __fastcall GetNearestArgA(int fromPos) +{ + int curPos = fromPos; + + for (curPos = fromPos - 1;;curPos--) + { + if (IsFlagSet(cfInstruction, curPos)) + { + if (IsFlagSet(cfProcStart, curPos)) break; + if (IsFlagSet(cfSetA, curPos)) return curPos; + } + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of nearest up instruction with segment prefix fs: +int __fastcall GetNearestUpPrefixFs(int fromPos) +{ + int _pos; + DISINFO _disInfo; + + assert(fromPos >= 0); + for (_pos = fromPos - 1; _pos >= 0; _pos--) + { + if (IsFlagSet(cfInstruction, _pos)) + { + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + if (_disInfo.SegPrefix == 4) return _pos; + } + if (IsFlagSet(cfProcStart, _pos)) break; + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of nearest up instruction from position fromPos +int __fastcall GetNearestUpInstruction(int fromPos) +{ + assert(fromPos >= 0); + for (int pos = fromPos - 1; pos >= 0; pos--) + { + if (IsFlagSet(cfInstruction, pos)) return pos; + if (IsFlagSet(cfProcStart, pos)) break; + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of N-th up instruction from position fromPos +int __fastcall GetNthUpInstruction(int fromPos, int N) +{ +if (fromPos < 0) +return -1; + assert(fromPos >= 0); + for (int pos = fromPos - 1; pos >= 0; pos--) + { + if (IsFlagSet(cfInstruction, pos)) + { + N--; + if (!N) return pos; + } + if (IsFlagSet(cfProcStart, pos)) break; + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of nearest up instruction from position fromPos +int __fastcall GetNearestUpInstruction(int fromPos, int toPos) +{ + assert(fromPos >= 0); + for (int pos = fromPos - 1; pos >= toPos; pos--) + { + if (IsFlagSet(cfInstruction, pos)) return pos; + if (IsFlagSet(cfProcStart, pos)) break; + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall GetNearestUpInstruction(int fromPos, int toPos, int no) +{ + assert(fromPos >= 0); + for (int pos = fromPos - 1; pos >= toPos; pos--) + { + if (IsFlagSet(cfInstruction, pos)) + { + no--; + if (!no) return pos; + } + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of nearest up instruction from position fromPos +int __fastcall GetNearestUpInstruction1(int fromPos, int toPos, char* Instruction) +{ + int len = strlen(Instruction); + int pos; + DISINFO DisInfo; + + assert(fromPos >= 0); + for (pos = fromPos - 1; pos >= toPos; pos--) + { + if (IsFlagSet(cfInstruction, pos)) + { + Disasm.Disassemble(Pos2Adr(pos), &DisInfo, 0); + if (len && !memicmp(DisInfo.Mnem, Instruction, len)) return pos; + } + if (IsFlagSet(cfProcStart, pos)) break; + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of nearest up instruction from position fromPos +int __fastcall GetNearestUpInstruction2(int fromPos, int toPos, char* Instruction1, char* Instruction2) +{ + int len1 = strlen(Instruction1), len2 = strlen(Instruction2); + int pos; + DISINFO DisInfo; + + assert(fromPos >= 0); + for (pos = fromPos - 1; pos >= toPos; pos--) + { + if (IsFlagSet(cfInstruction, pos)) + { + Disasm.Disassemble(Pos2Adr(pos), &DisInfo, 0); + if ((len1 && !memicmp(DisInfo.Mnem, Instruction1, len1)) || + (len2 && !memicmp(DisInfo.Mnem, Instruction2, len2))) return pos; + } + if (IsFlagSet(cfProcStart, pos)) break; + } + return -1; +} +//--------------------------------------------------------------------------- +//Return position of nearest down instruction from position fromPos +int __fastcall GetNearestDownInstruction(int fromPos) +{ + int instrLen; + DISINFO DisInfo; + + assert(fromPos >= 0); + instrLen = Disasm.Disassemble(Pos2Adr(fromPos), &DisInfo, 0); + if (!instrLen) return -1; + return fromPos + instrLen; +} +//--------------------------------------------------------------------------- +//Return position of nearest down "Instruction" from position fromPos +int __fastcall GetNearestDownInstruction(int fromPos, char* Instruction) +{ + int instrLen, len = strlen(Instruction); + int curPos = fromPos; + DISINFO DisInfo; + + assert(fromPos >= 0); + while (1) + { + instrLen = Disasm.Disassemble(Pos2Adr(curPos), &DisInfo, 0); + if (!instrLen) + { + curPos++; + continue; + } + if (len && !memcmp(DisInfo.Mnem, Instruction, len)) return curPos; + if (DisInfo.Ret) break; + curPos += instrLen; + } + return -1; +} +//--------------------------------------------------------------------------- +//-1 - error +//0 - simple if +//1 - jcc down +//2 - jcc up +//3 - jmp down +//4 - jump up +int __fastcall BranchGetPrevInstructionType(DWORD fromAdr, DWORD* jmpAdr, PLoopInfo loopInfo) +{ + int _pos; + DISINFO _disInfo; + + *jmpAdr = 0; + _pos = GetNearestUpInstruction(Adr2Pos(fromAdr)); + if (_pos == -1) return -1; + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + if (_disInfo.Branch) + { + if (IsExit(_disInfo.Immediate)) return 0; + if (_disInfo.Conditional) + { + if (_disInfo.Immediate > CodeBase + _pos) + { + if (loopInfo && loopInfo->BreakAdr == _disInfo.Immediate) return 0; + return 1; + } + return 2; + } + if (_disInfo.Immediate > CodeBase + _pos) + { + *jmpAdr = _disInfo.Immediate; + return 3; + } + //jmp after jmp @HandleFinally + if (IsFlagSet(cfFinally, _pos)) + { + _pos = GetNearestUpInstruction(Adr2Pos(_disInfo.Immediate)); + //push Adr + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + if (_disInfo.Immediate == fromAdr) return 0; + *jmpAdr = _disInfo.Immediate; + return 3; + } + return 4; + } + return 0; +} +//--------------------------------------------------------------------------- +bool __fastcall IsFlagSet(DWORD flag, int pos) +{ +//!!! +if (pos < 0 || pos >= TotalSize) +{ + dummy = 1; + return false; +} + assert(pos >= 0 && pos < TotalSize); + return (Flags[pos] & flag); +} +//--------------------------------------------------------------------------- +void __fastcall SetFlag(DWORD flag, int pos) +{ +//!!! +if (pos < 0 || pos >= TotalSize) +{ + dummy = 1; + return; +} + assert(pos >= 0 && pos < TotalSize); + Flags[pos] |= flag; +} +//--------------------------------------------------------------------------- +void __fastcall SetFlags(DWORD flag, int pos, int num) +{ +//!!! +if (pos < 0 || pos + num >= TotalSize) +{ +dummy = 1; +return; +} + assert(pos >= 0 && pos + num < TotalSize); + for (int i = pos; i < pos + num; i++) + { + Flags[i] |= flag; + } +} +//--------------------------------------------------------------------------- +void __fastcall ClearFlag(DWORD flag, int pos) +{ +//!!! +if (pos < 0 || pos >= TotalSize) +{ + dummy = 1; + return; +} + assert(pos >= 0 && pos < TotalSize); + Flags[pos] &= ~flag; +} +//--------------------------------------------------------------------------- +void __fastcall ClearFlags(DWORD flag, int pos, int num) +{ +if (pos < 0 || pos + num > TotalSize) +{ +dummy = 1; +return; +} + assert(pos >= 0 && pos + num <= TotalSize); + for (int i = pos; i < pos + num; i++) + { + Flags[i] &= ~flag; + } +} +//--------------------------------------------------------------------------- +//pInfo must contain pInfo-> +int __fastcall GetProcRetBytes(MProcInfo* pInfo) +{ + int _pos = pInfo->DumpSz - 1; + DWORD _curAdr = CodeBase + _pos; + DISINFO _disInfo; + + while (_pos >= 0) + { + Disasm.Disassemble(pInfo->Dump + _pos, (__int64)_curAdr, &_disInfo, 0); + if (_disInfo.Ret) + { + if (_disInfo.OpType[0] == otIMM)//ImmPresent) + return _disInfo.Immediate; + else + return 0; + } + _pos--; _curAdr--; + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall GetProcSize(DWORD fromAdr) +{ + int _size = 0; + PInfoRec recN = GetInfoRec(fromAdr); + if (recN && recN->procInfo) _size = recN->procInfo->procSize; + if (!_size) _size = FMain_11011981->EstimateProcSize(fromAdr); + return _size; +/* + int pos, size = 0; + for (pos = Adr2Pos(fromAdr); pos < TotalSize; pos++) + { + size++; + if (IsFlagSet(cfProcEnd, pos)) break; + } + return size; +*/ +} +//--------------------------------------------------------------------------- +int __fastcall StrGetRecordSize(String str) +{ + int _size = 0; + int _bpos = str.Pos("size="); + int _epos = str.LastDelimiter("\n"); + if (_bpos && _epos) + { + String _sz = str.SubString(_bpos + 5, _epos - _bpos - 5); + _size = StrToInt("$" + _sz); + } + return _size; +} +//--------------------------------------------------------------------------- +int __fastcall StrGetRecordFieldOffset(String str) +{ + int _offset = -1; + int _bpos = str.Pos("//"); + int _epos = str.LastDelimiter("\n"); + if (_bpos && _epos) + { + String _ofs = str.SubString(_bpos + 2, _epos - _bpos - 2); + _offset = StrToInt("$" + _ofs); + } + return _offset; +} +//--------------------------------------------------------------------------- +String __fastcall StrGetRecordFieldName(String str) +{ + String _name = ""; + int _pos = str.Pos(":"); + if (_pos) + _name = str.SubString(1, _pos - 1); + return _name; +} +//--------------------------------------------------------------------------- +String __fastcall StrGetRecordFieldType(String str) +{ + String _type = ""; + int _epos = str.LastDelimiter(";"); + int _bpos = str.Pos(":"); + if (_bpos && _epos) + _type = str.SubString(_bpos + 1, _epos - _bpos - 1); + return _type; +} +//--------------------------------------------------------------------------- +int __fastcall GetRecordSize(String AName) +{ + BYTE _len; + WORD *_uses; + int _idx, _pos, _size; + MTypeInfo _tInfo; + PTypeRec _recT; + String _str, _sz; + + //File + String _recFileName = FMain_11011981->WrkDir + "\\types.idr"; + FILE* _recFile = fopen(_recFileName.c_str(), "rt"); + if (_recFile) + { + while (1) + { + if (!fgets(StringBuf, 1024, _recFile)) break; + _str = String(StringBuf); + if (_str.Pos(AName + "=") == 1) + { + _size = StrGetRecordSize(_str); + fclose(_recFile); + return _size; + } + } + fclose(_recFile); + } + //KB + _uses = KnowledgeBase.GetTypeUses(AName.c_str()); + _idx = KnowledgeBase.GetTypeIdxByModuleIds(_uses, AName.c_str()); + if (_uses) delete[] _uses; + + if (_idx != -1) + { + _idx = KnowledgeBase.TypeOffsets[_idx].NamId; + if (KnowledgeBase.GetTypeInfo(_idx, INFO_DUMP, &_tInfo)) + return _tInfo.Size; + } + //RTTI + _recT = GetOwnTypeByName(AName); + if (_recT && _recT->kind == ikRecord) + { + _pos = Adr2Pos(_recT->adr); + _pos += 4;//SelfPtr + _pos++;//TypeKind + _len = Code[_pos]; _pos += _len + 1;//Name + return *((DWORD*)(Code + _pos)); + } + //Manual + return 0; +} +//--------------------------------------------------------------------------- +PFIELDINFO __fastcall GetClassField(String TypeName, int Offset) +{ + int n, Ofs1, Ofs2; + DWORD classAdr, prevClassAdr = 0; + PInfoRec recN; + PFIELDINFO fInfo1, fInfo2; + + classAdr = GetClassAdr(TypeName); + while (classAdr && Offset < GetClassSize(classAdr)) + { + prevClassAdr = classAdr; + classAdr = GetParentAdr(classAdr); + } + classAdr = prevClassAdr; + if (classAdr) + { + recN = GetInfoRec(classAdr); + if (recN && recN->vmtInfo && recN->vmtInfo->fields) + { + for (n = 0; n < recN->vmtInfo->fields->Count; n++) + { + fInfo1 = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; Ofs1 = fInfo1->Offset; + if (n == recN->vmtInfo->fields->Count - 1) + { + Ofs2 = GetClassSize(classAdr); + } + else + { + fInfo2 = (PFIELDINFO)recN->vmtInfo->fields->Items[n + 1]; + Ofs2 = fInfo2->Offset; + } + if (Offset >= Ofs1 && Offset < Ofs2) + { + return fInfo1; + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall GetRecordField(String ARecType, int AOfs, String& name, String& type) +{ + bool _brk; + BYTE _len, _numOps, _kind; + char *p, *ps; + WORD _dw; + WORD *_uses; + int n, m, k, _idx, _pos, _elNum, Ofs, Ofs1, Ofs2, _case, _fieldsNum, _size; + DWORD _typeAdr; + PTypeRec _recT; + MTypeInfo _tInfo; + String _str, _prevstr, _name, _typeName, _ofs, _sz, _result = ""; + int _fieldOfsets[1024]; + CaseInfo _cases[256]; + + if (ARecType == "") return -1; + + name = ""; type = ""; + + _pos = ARecType.LastDelimiter("."); + if (_pos > 1 && ARecType[_pos + 1] != ':') + ARecType = ARecType.SubString(_pos + 1, ARecType.Length()); + + //File + String _recFileName = FMain_11011981->WrkDir + "\\types.idr"; + FILE* _recFile = fopen(_recFileName.c_str(), "rt"); + if (_recFile) + { + while (1) + { + if (!fgets(StringBuf, 1024, _recFile)) break; + _str = String(StringBuf); + if (_str.Pos(ARecType + "=") == 1) + { + _size = StrGetRecordSize(_str); + + _prevstr = ""; _brk = false; + //Ofs2 = _size; + while (1) + { + if (!fgets(StringBuf, 1024, _recFile)) break; + _str = String(StringBuf); + Ofs1 = StrGetRecordFieldOffset(_prevstr); + if (_str.Pos("end;")) + { + Ofs2 = _size; + _brk = true; + } + else + Ofs2 = StrGetRecordFieldOffset(_str); + if (Ofs1 >= 0 && AOfs >= Ofs1 && AOfs < Ofs2) + { + name = StrGetRecordFieldName(_prevstr); + type = StrGetRecordFieldType(_prevstr); + fclose(_recFile); + return Ofs1; + } + if (_brk) break; + _prevstr = _str; + } + fclose(_recFile); + } + } + fclose(_recFile); + } + int tries = 5; + while (tries >= 0) + { + tries--; + //KB + _uses = KnowledgeBase.GetTypeUses(ARecType.c_str()); + _idx = KnowledgeBase.GetTypeIdxByModuleIds(_uses, ARecType.c_str()); + if (_uses) delete[] _uses; + + if (_idx != -1) + { + _idx = KnowledgeBase.TypeOffsets[_idx].NamId; + if (KnowledgeBase.GetTypeInfo(_idx, INFO_FIELDS, &_tInfo)) + { + if (_tInfo.FieldsNum) + { + memset(_cases, 0, 256 * sizeof(CaseInfo)); + p = _tInfo.Fields; + for (m = 0, n = 0; n < _tInfo.FieldsNum; n++) + { + p++;//scope + p += 4;//offset + _case = *((int*)p); p += 4;//case + if (!_cases[m].count) + { + _cases[m].caseno = _case; + } + else if (_cases[m].caseno != _case) + { + m++; + _cases[m].caseno = _case; + } + _cases[m].count++; + _len = *((WORD*)p); p += _len + 3;//name + _len = *((WORD*)p); p += _len + 3;//type + } + + for (m = 0; m < 256; m++) + { + if (_cases[m].count) + { + p = _tInfo.Fields; + for (n = 0, k = 0; n < _tInfo.FieldsNum; n++) + { + ps = p; + p++;//scope + Ofs1 = *((int*)p); p += 4;//offset + _case = *((int*)p); p += 4;//case + _len = *((WORD*)p); p += _len + 3;//name + _len = *((WORD*)p); p += _len + 3;//type + if (_case == _cases[m].caseno) + { + if (k == _cases[m].count - 1) + { + Ofs2 = GetRecordSize(ARecType); + } + else + { + Ofs2 = *((int*)(p + 1)); + } + if (AOfs >= Ofs1 && AOfs < Ofs2) + { + p = ps; + p++;//scope + Ofs1 = *((int*)p); p += 4;//offset + p += 4;//case + _len = *((WORD*)p); p += 2; + name = String(p, _len); p += _len + 1; + _len = *((WORD*)p); p += 2; + type = String(p, _len); p += _len + 1; + return Ofs1; + } + k++; + } + } + } + } + } + else if (_tInfo.Decl != "") + { + ARecType = _tInfo.Decl; + //Ofs = GetRecordField(_tInfo.Decl, AOfs, name, type); + //if (Ofs >= 0) + // return Ofs; + } + } + } + } + //RTTI + _recT = GetOwnTypeByName(ARecType); + if (_recT && _recT->kind == ikRecord) + { + _pos = Adr2Pos(_recT->adr); + _pos += 4;//SelfPtr + _pos++;//TypeKind + _len = Code[_pos]; _pos++; + _name = String((char*)(Code + _pos), _len); _pos += _len;//Name + _pos += 4;//Size + _elNum = *((DWORD*)(Code + _pos)); _pos += 4; + for (n = 0; n < _elNum; n++) + { + _typeAdr = *((DWORD*)(Code + _pos)); _pos += 4; + Ofs1 = *((DWORD*)(Code + _pos)); _pos += 4; + if (n == _elNum - 1) + Ofs2 = 0; + else + Ofs2 = *((DWORD*)(Code + _pos + 4)); + if (AOfs >= Ofs1 && AOfs < Ofs2) + { + name = _name + ".f" + Val2Str0(Ofs1); + type = GetTypeName(_typeAdr); + return Ofs1; + } + + } + if (DelphiVersion >= 2010) + { + //NumOps + _numOps = Code[_pos]; _pos++; + for (n = 0; n < _numOps; n++) //RecOps + { + _pos += 4; + } + _elNum = *((DWORD*)(Code + _pos)); _pos += 4; //RecFldCnt + + for (n = 0; n < _elNum; n++) + { + _typeAdr = *((DWORD*)(Code + _pos)); _pos += 4; + Ofs1 = *((DWORD*)(Code + _pos)); _pos += 4; + _pos++;//Flags + _len = Code[_pos]; _pos++; + _name = String((char*)(Code + _pos), _len); _pos += _len; + //AttrData + _dw = *((WORD*)(Code + _pos)); + _pos += _dw;//ATR!! + + if (n == _elNum - 1) + Ofs2 = 0; + else + Ofs2 = *((DWORD*)(Code + _pos + 4)); + + if (AOfs >= Ofs1 && AOfs < Ofs2) + { + if (_name != "") + name = _name; + else + name = "f" + Val2Str0(Ofs1); + type = GetTypeName(_typeAdr); + return Ofs1; + } + } + } + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall GetField(String TypeName, int Offset, String& name, String& type) +{ + int size, kind, ofs; + PFIELDINFO fInfo; + String _fname, _ftype, _type = TypeName; + + _fname = ""; _ftype = ""; + + while (Offset >= 0) + { + kind = GetTypeKind(_type, &size); + if (kind != ikVMT && kind != ikArray && kind != ikRecord && kind != ikDynArray) break; + + if (kind == ikVMT) + { + if (!Offset) return 0; + fInfo = GetClassField(_type, Offset); + if (name != "") + name += "."; + if (fInfo->Name != "") + name += fInfo->Name; + else + name += "f" + IntToHex((int)fInfo->Offset, 0); + type = fInfo->Type; + + _type = fInfo->Type; + Offset -= fInfo->Offset; + //if (!Offset) return fInfo->Offset; + continue; + } + if (kind == ikRecord) + { + ofs = GetRecordField(_type, Offset, _fname, _ftype); + if (ofs == -1) return -1; + if (name != "") + name += "."; + name += _fname; + type = _ftype; + + _type = _ftype; + Offset -= ofs; + //if (!Offset) return ofs; + continue; + } + if (kind == ikArray || kind == ikDynArray) + { + //name += "[]"; + break; + } + } + return Offset; +} +//--------------------------------------------------------------------------- +String __fastcall GetRecordFields(int AOfs, String ARecType) +{ + String _name, _typeName; + + if (ARecType == "" || GetField(ARecType, AOfs, _name, _typeName) < 0) return ""; + return _name + ":" + _typeName; +} +//--------------------------------------------------------------------------- +String __fastcall GetAsmRegisterName(int Idx) +{ + assert(Idx >= 0 && Idx < 32); + if (Idx >= 31) return "st(" + String(Idx - 31) + ")"; + if (Idx == 30) return "st"; + if (Idx >= 24) return String(SegRegTab[Idx - 24]); + if (Idx >= 16) return String(Reg32Tab[Idx - 16]); + if (Idx >= 8) return String(Reg16Tab[Idx - 8]); + return String(Reg8Tab[Idx]); +} +//--------------------------------------------------------------------------- +String __fastcall GetDecompilerRegisterName(int Idx) +{ + assert(Idx >= 0 && Idx < 32); + if (Idx >= 16) return UpperCase(Reg32Tab[Idx - 16]); + if (Idx >= 8) return UpperCase(Reg32Tab[Idx - 8]); + return UpperCase(Reg32Tab[Idx]); +} +//--------------------------------------------------------------------------- +bool __fastcall IsValidModuleName(int len, int pos) +{ + if (!len) return false; + for (int i = pos; i < pos + len; i++) + { + BYTE b = *(Code + i); + if (b < ' ' || b == ':' || (b & 0x80)) return false; + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall IsValidName(int len, int pos) +{ + if (!len) return false; + for (int i = pos; i < pos + len; i++) + { + //if (IsFlagSet(cfCode, i)) return false; + + BYTE b = *(Code + i); + //first symbol may be letter or '_' or '.' or ':' + if (i == pos) + { + if ((b >= 'A' && b <= 'z') || b == '.' || b == '_' || b == ':') + continue; + else + return false; + } + if (b & 0x80) return false; + //if ((b < '0' || b > 'z') && b != '.' && b != '_' && b != ':' && b != '$') return false; + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall IsValidString(int len, int pos) +{ + if (len < 5) return false; + for (int i = pos; i < pos + len; i++) + { + //if (IsFlagSet(cfCode, i)) return false; + + BYTE b = *(Code + i); + if (b < ' ' && b != '\t' && b != '\n' && b != '\r') return false; + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall IsValidCString(int pos) +{ + int len = 0; + for (int i = pos; i < pos + 1024; i++) + { + BYTE b = *(Code + i); + //if (IsFlagSet(cfCode, i)) break; + if (!b) return (len >= 5); + if (b < ' ' && b != '\t' && b != '\n' && b != '\r') break; + len++; + } + return false; +} +//--------------------------------------------------------------------------- +DWORD __fastcall GetParentAdr(DWORD Adr) +{ + if (!IsValidImageAdr(Adr)) return 0; + + DWORD vmtAdr = Adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtParent; + DWORD adr = *((DWORD*)(Code + pos)); + if (IsValidImageAdr(adr) && IsFlagSet(cfImport, Adr2Pos(adr))) + return 0; + + if (DelphiVersion == 2 && adr) adr += cVmtSelfPtr; + return adr; +} +//--------------------------------------------------------------------------- +DWORD __fastcall GetChildAdr(DWORD Adr) +{ + if (!IsValidImageAdr(Adr)) return 0; + for (int m = 0; m < VmtList->Count; m++) + { + PVmtListRec recV = (PVmtListRec)VmtList->Items[m]; + if (recV->vmtAdr != Adr && IsInheritsByAdr(recV->vmtAdr, Adr)) + return recV->vmtAdr; + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall GetClassSize(DWORD adr) +{ + if (!IsValidImageAdr(adr)) return 0; + + DWORD vmtAdr = adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtInstanceSize; + int size = *((int*)(Code + pos)); + if (DelphiVersion >= 2009) return size - 4; + return size; +} +//--------------------------------------------------------------------------- +String __fastcall GetClsName(DWORD adr) +{ + if (!IsValidImageAdr(adr)) return ""; + + DWORD vmtAdr = adr - cVmtSelfPtr; + DWORD pos = Adr2Pos(vmtAdr) + cVmtClassName; + if (IsFlagSet(cfImport, pos)) + { + PInfoRec recN = GetInfoRec(vmtAdr + cVmtClassName); + return recN->GetName(); + } + DWORD nameAdr = *((DWORD*)(Code + pos)); + if (!IsValidImageAdr(nameAdr)) + return ""; + + pos = Adr2Pos(nameAdr); + BYTE len = Code[pos]; pos++; + return String((char*)&Code[pos], len); +} +//--------------------------------------------------------------------------- +DWORD __fastcall GetClassAdr(const String& AName) +{ + String name; + + if (AName.IsEmpty()) return 0; + + DWORD adr = FindClassAdrByName(AName); + if (adr) return adr; + + int pos = AName.Pos("."); + if (pos) + { + //type as .XX or array[XX..XX] of XXX - skip + if (pos == 1 || AName[pos + 1] == '.') return 0; + name = AName.SubString(pos + 1, AName.Length()); + } + else + name = AName; + + const int vmtCnt = VmtList->Count; + for (int n = 0; n < vmtCnt; n++) + { + PVmtListRec recV = (PVmtListRec)VmtList->Items[n]; + if (SameText(recV->vmtName, name)) + { + adr = recV->vmtAdr; + AddClassAdr(adr, name); + return adr; + } + } + return 0; +} + +//--------------------------------------------------------------------------- +int __fastcall GetParentSize(DWORD Adr) +{ + return GetClassSize(GetParentAdr(Adr)); +} +//--------------------------------------------------------------------------- +String __fastcall GetParentName(DWORD Adr) +{ + DWORD adr = GetParentAdr(Adr); + if (!adr) return ""; + return GetClsName(adr); +} +//--------------------------------------------------------------------------- +String __fastcall GetParentName(const String& ClassName) +{ + return GetParentName(GetClassAdr(ClassName)); +} +//--------------------------------------------------------------------------- +//Adr1 inherits Adr2 (Adr1 >= Adr2) +bool __fastcall IsInheritsByAdr(const DWORD Adr1, const DWORD Adr2) +{ + DWORD adr = Adr1; + while (adr) + { + if (adr == Adr2) return true; + adr = GetParentAdr(adr); + } + return false; +} +//--------------------------------------------------------------------------- +//Name1 >= Name2 +bool __fastcall IsInheritsByClassName(const String& Name1, const String& Name2) +{ + DWORD adr = GetClassAdr(Name1); + while (adr) + { + if (SameText(GetClsName(adr), Name2)) return true; + adr = GetParentAdr(adr); + } + return false; +} +//--------------------------------------------------------------------------- +bool __fastcall IsInheritsByProcName(const String& Name1, const String& Name2) +{ + return (IsInheritsByClassName(ExtractClassName(Name1), ExtractClassName(Name2)) && + SameText(ExtractProcName(Name1), ExtractProcName(Name2))); +} +//--------------------------------------------------------------------------- +String __fastcall TransformString(char* str, int len) +{ + bool s = true;//true - print string, false - print #XX + BYTE c, *p = str; + String res = ""; + + for (int k = 0; k < len; k++) + { + c = *p; p++; + if (!(c & 0x80) && c <= 13) + { + if (s) + { + if (k) res += "'+"; + } + else + res += "+"; + res += "#" + String((int)c); + s = false; + } + else + { + if (s) + { + if (!k) res += "'"; + } + else + res += "+"; + s = true; + } + if (c == 0x22) + res += "\""; + else if (c == 0x27) + res += "'"; + else if (c == 0x5C) + res += "\\"; + else if (c > 13) + res += (char)c; + } + if (s) res += "'"; + return res; +} +//--------------------------------------------------------------------------- +String __fastcall TransformUString(WORD codePage, wchar_t* data, int len) +{ + if (!IsValidCodePage(codePage)) codePage = CP_ACP; + int nChars = WideCharToMultiByte(codePage, 0, data, -1, 0, 0, 0, 0); + if (!nChars) return ""; + char* tmpBuf = new char[nChars + 1]; + WideCharToMultiByte(codePage, 0, data, -1, tmpBuf, nChars, 0, 0); + tmpBuf[nChars] = 0; + String res = QuotedStr(tmpBuf); + delete[] tmpBuf; + return res; +} +//--------------------------------------------------------------------------- +//Get stop address for analyzing virtual tables +DWORD __fastcall GetStopAt(DWORD VmtAdr) +{ + int m; + DWORD pos, pointer, stopAt = CodeBase + TotalSize; + + if (DelphiVersion != 2) + { + pos = Adr2Pos(VmtAdr) + cVmtIntfTable; + for (m = cVmtIntfTable; m != cVmtInstanceSize; m += 4, pos += 4) + { + pointer = *((DWORD*)(Code + pos)); + if (pointer >= VmtAdr && pointer < stopAt) stopAt = pointer; + } + } + else + { + pos = Adr2Pos(VmtAdr) + cVmtInitTable; + for (m = cVmtInitTable; m != cVmtInstanceSize; m += 4, pos += 4) + { + if (Adr2Pos(VmtAdr) < 0) + return 0; + pointer = *((DWORD*)(Code + pos)); + if (pointer >= VmtAdr && pointer < stopAt) stopAt = pointer; + } + } + return stopAt; +} +//--------------------------------------------------------------------------- +String __fastcall GetTypeName(DWORD adr) +{ + if (!IsValidImageAdr(adr)) return "?"; + if (IsFlagSet(cfImport, Adr2Pos(adr))) + { + PInfoRec recN = GetInfoRec(adr); + return recN->GetName(); + } + + int pos = Adr2Pos(adr); + if (IsFlagSet(cfRTTI, pos)) + pos += 4; + else + adr -= 4; + //TypeKind + BYTE kind = *(Code + pos); pos++; + BYTE len = *(Code + pos); pos++; + String Result = String((char*)(Code + pos), len); + if (Result.Pos(":") > 0) + Result = TransformShadowName(Result, kind, adr);//SHADOW + return Result; +} +//--------------------------------------------------------------------------- +String __fastcall GetDynaInfo(DWORD adr, WORD id, DWORD* dynAdr) +{ + int m; + DWORD classAdr = adr; + PInfoRec recN; + PMethodRec recM; + + *dynAdr = 0; + + if (!IsValidCodeAdr(adr)) return ""; + + while (classAdr) + { + recN = GetInfoRec(classAdr); + if (recN && recN->vmtInfo && recN->vmtInfo->methods) + { + for (m = 0; m < recN->vmtInfo->methods->Count; m++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[m]; + if (recM->kind == 'D' && recM->id == id) + { + *dynAdr = recM->address; + if (recM->name != "") return recM->name; + return "";//GetDefaultProcName(recM->address); + } + } + } + classAdr = GetParentAdr(classAdr); + } + return ""; +} +//--------------------------------------------------------------------------- +String __fastcall GetDynArrayTypeName(DWORD adr) +{ + Byte len; + int pos; + + pos = Adr2Pos(adr); + pos += 4; + pos++;//Kind + len = Code[pos]; pos++; + pos += len;//Name + pos += 4;//elSize + return GetTypeName(*((DWORD*)(Code + pos))); +} +//--------------------------------------------------------------------------- +int __fastcall GetTypeSize(String AName) +{ + int idx = -1; + WORD* uses; + MTypeInfo tInfo; + + uses = KnowledgeBase.GetTypeUses(AName.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AName.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) + { + if (tInfo.Size) return tInfo.Size; + } + } + return 4; +} +//--------------------------------------------------------------------------- +#define TypeKindsNum 22 +String TypeKinds[TypeKindsNum] = +{ + "Unknown", + "Integer", + "Char", + "Enumeration", + "Float", + "ShortString", + "Set", + "Class", + "Method", + "WChar", + "AnsiString", + "WideString", + "Variant", + "Array", + "Record", + "Interface", + "Int64", + "DynArray", + "UString", + "ClassRef", + "Pointer", + "Procedure" +}; +//--------------------------------------------------------------------------- +String __fastcall TypeKind2Name(BYTE kind) +{ + if (kind < TypeKindsNum) return TypeKinds[kind]; + else return ""; +} +//--------------------------------------------------------------------------- +DWORD __fastcall GetOwnTypeAdr(String AName) +{ + if (AName == "") return 0; + PTypeRec recT = GetOwnTypeByName(AName); + if (recT) return recT->adr; + return 0; +} +//--------------------------------------------------------------------------- +PTypeRec __fastcall GetOwnTypeByName(String AName) +{ + if (AName == "") return 0; + for (int m = 0; m < OwnTypeList->Count; m++) + { + PTypeRec recT = (PTypeRec)OwnTypeList->Items[m]; + if (SameText(recT->name, AName)) return recT; + } + return 0; +} +//--------------------------------------------------------------------------- +String __fastcall GetTypeDeref(String ATypeName) +{ + int idx = -1; + WORD* uses; + MTypeInfo tInfo; + + if (ATypeName[1] == '^') return ATypeName.SubString(2, ATypeName.Length()); + + //Scan knowledgeBase + uses = KnowledgeBase.GetTypeUses(ATypeName.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, ATypeName.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) + { + if (tInfo.Decl != "" && tInfo.Decl[1] == '^') + return tInfo.Decl.SubString(2, tInfo.Decl.Length()); + } + } + return ""; +} +//--------------------------------------------------------------------------- +int __fastcall GetRTTIRecordSize(DWORD adr) +{ + BYTE len; + int pos, kind, _ap; + + _ap = Adr2Pos(adr); pos = _ap; + pos += 4; + kind = Code[pos]; pos++; + len = Code[pos]; pos += len + 1; + + if (kind == ikRecord) + return *((int*)(Code + pos)); + else + return 0; +} +//--------------------------------------------------------------------------- +BYTE __fastcall GetTypeKind(DWORD Adr) +{ + int _ap = Adr2Pos(Adr); + int pos = _ap; + pos += 4; + return Code[pos]; +} +//--------------------------------------------------------------------------- +BYTE __fastcall GetTypeKind(String AName, int* size) +{ + BYTE res, kind; + int pos, idx = -1; + WORD* uses; + MTypeInfo tInfo; + String name, typeName, str, sz; + + *size = 4; + if (AName != "") + { + if (AName.Pos("array")) + { + if (AName.Pos("array of")) return ikDynArray; + return ikArray; + } + + pos = AName.LastDelimiter("."); + if (pos > 1 && AName[pos + 1] != ':') + name = AName.SubString(pos + 1, AName.Length()); + else + name = AName; + + if (SameText(name, "Byte")) + { + *size = 1; + return ikInteger; + } + if (SameText(name, "Word")) + { + *size = 2; + return ikInteger; + } + + if (SameText(name, "Dword")) + return ikInteger; + + if (name[1] == '^' || SameText(name, "Pointer")) + return ikPointer; + + if (SameText(name, "ShortString")) + { + *size = 256; + return ikString; + } + if (SameText(name, "String") || SameText(name, "AnsiString")) + return ikLString; + + if (SameText(name, "WideString")) + return ikWString; + + if (SameText(name, "UnicodeString") || SameText(name, "UString")) + return ikUString; + + if (SameText(name, "PChar") || SameText(name, "PAnsiChar")) + return ikCString; + + if (SameText(name, "PWideChar")) + return ikWCString; + + if (SameText(name, "Variant")) + { + *size = 16; + return ikVariant; + } + + if (SameText(name, "Int64")) + { + *size = 8; + return ikInt64; + } + if (SameText(name, "Single")) + { + return ikFloat; + } + + //RTTI + PTypeRec recT = GetOwnTypeByName(name); + if (recT) + { + *size = GetRTTIRecordSize(recT->adr); + if (!*size) *size = 4; + return recT->kind; + } + + //Scan KB + uses = KnowledgeBase.GetTypeUses(name.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, name.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) + { + if (tInfo.Kind == 'Z') //drAlias??? + { + *size = 1; + return ikUnknown; + } + if (tInfo.Decl != "" && tInfo.Decl[1] == '^') + { + *size = 1; + return ikUnknown; + //res = GetTypeKind(tInfo.Decl.SubString(2, tInfo.Decl.Length()), size); + //if (res) return res; + //return 0; + } + *size = tInfo.Size; + switch (tInfo.Kind) + { + case drRangeDef: + return ikEnumeration; + case drPtrDef: + return ikMethod; + case drProcTypeDef: + return ikMethod; + case drSetDef: + return ikSet; + case drRecDef: + return ikRecord; + case drInterfaceDef: + return ikInterface; + } + if (tInfo.Decl != "" && tInfo.Decl != AName) + { + res = GetTypeKind(tInfo.Decl, size); + if (res) + { + return res; + } + } + } + } + + if (SameText(name, "Boolean") || + SameText(name, "ByteBool") || + SameText(name, "WordBool") || + SameText(name, "LongBool")) + { + return ikEnumeration; + } + if (SameText(name, "ShortInt") || + SameText(name, "SmallInt") || + SameText(name, "Integer") || + SameText(name, "LongInt") || + SameText(name, "LongWord") || + SameText(name, "Cardinal")) + { + return ikInteger; + } + if (SameText(name, "Char")) + { + return ikChar; + } + if (SameText(name, "Text") || SameText(name, "File")) + { + return ikRecord; + } + + if (SameText(name, "Real48") || + SameText(name, "Real") || + SameText(name, "Double") || + SameText(name, "TDate") || + SameText(name, "TTime") || + SameText(name, "TDateTime")|| + SameText(name, "Comp") || + SameText(name, "Currency")) + { + *size = 8; + return ikFloat; + } + if (SameText(name, "Extended")) + { + *size = 12; + return ikFloat; + } + //if (SameText(name, "Pointer")) return ikPointer; + + //File + /* + String recFileName = FMain_11011981->WrkDir + "\\types.idr"; + FILE* recFile = fopen(recFileName.c_str(), "rt"); + if (recFile) + { + while (1) + { + if (!fgets(StringBuf, 1024, recFile)) break; + str = String(StringBuf); + if (str.Pos(AName + "=") == 1) + { + if (str.Pos("=record")) + { + *size = StrGetRecordSize(str); + fclose(recFile); + return ikRecord; + } + } + } + fclose(recFile); + } + */ + //KB + //May be Interface name + if (AName[1] == 'I') + { + AName[1] = 'T'; + if (GetTypeKind(AName, size) == ikVMT) + { + return ikInterface; + } + } + } + *size = 1; + return ikUnknown; +} +//--------------------------------------------------------------------------- +int __fastcall GetPackedTypeSize(String AName) +{ + int _size; + if (SameText(AName, "Boolean") || + SameText(AName, "ShortInt") || + SameText(AName, "Byte") || + SameText(AName, "Char")) + { + return 1; + } + if (SameText(AName, "SmallInt") || + SameText(AName, "Word")) + { + return 2; + } + if (SameText(AName, "Dword") || + SameText(AName, "Integer") || + SameText(AName, "LongInt") || + SameText(AName, "LongWord") || + SameText(AName, "Cardinal") || + SameText(AName, "Single")) + { + return 4; + } + if (SameText(AName, "Real48")) + { + return 6; + } + if (SameText(AName, "Real") || + SameText(AName, "Double") || + SameText(AName, "Comp") || + SameText(AName, "Currency") || + SameText(AName, "Int64")) + { + return 8; + } + if (SameText(AName, "Extended")) + { + return 10; + } + if (GetTypeKind(AName, &_size) == ikRecord) + { + return GetRecordSize(AName); + } + return 4; +} +//--------------------------------------------------------------------------- +//return string representation of immediate value with comment +String __fastcall GetImmString(int Val) +{ + String _res; + String _res0 = String((int)Val); + if (Val > -16 && Val < 16) return _res0; + _res = String("$") + Val2Str0(Val); + if (!IsValidImageAdr(Val)) _res += "{" + _res0 + "}"; + return _res; +} +//--------------------------------------------------------------------------- +String __fastcall GetImmString(String TypeName, int Val) +{ + int _size; + String _str, _default = GetImmString(Val); + BYTE _kind = GetTypeKind(TypeName, &_size); + if (!Val && (_kind == ikString || _kind == ikLString || _kind == ikWString || _kind == ikUString)) return "''"; + if (!Val && (_kind == ikClass || _kind == ikVMT)) return "Nil"; + if (_kind == ikEnumeration) + { + _str = GetEnumerationString(TypeName, Val); + if (_str != "") return _str; + return _default; + } + if (_kind == ikChar) return Format("'%s'", ARRAYOFCONST(((Char)Val))); + return _default; +} +//--------------------------------------------------------------------------- +PInfoRec __fastcall GetInfoRec(DWORD adr) +{ + int pos = Adr2Pos(adr); + if (pos >= 0) + return Infos[pos]; + + int _idx = BSSInfos->IndexOf(Val2Str8(adr)); + if (_idx != -1) + return (PInfoRec)BSSInfos->Objects[_idx]; + + return 0; +} +//--------------------------------------------------------------------------- +String __fastcall GetEnumerationString(String TypeName, Variant Val) +{ + BYTE len; + int n, pos, _val, idx; + DWORD adr, typeAdr, minValue, maxValue, minValueB, maxValueB; + char *p, *b, *e; + WORD *uses; + MTypeInfo tInfo; + String clsName; + + if (Val.Type() == varString) return String(Val); + + _val = Val; + + if (SameText(TypeName, "Boolean") || + SameText(TypeName, "ByteBool") || + SameText(TypeName, "WordBool") || + SameText(TypeName, "LongBool")) + { + if (_val) + return "True"; + else + return "False"; + } + + adr = GetOwnTypeAdr(TypeName); + //RTTI exists + if (IsValidImageAdr(adr)) + { + pos = Adr2Pos(adr); + pos += 4; + //typeKind + pos++; + len = Code[pos]; pos++; + clsName = String((char*)(Code + pos), len); pos += len; + //ordType + pos++; + minValue = *((DWORD*)(Code + pos)); pos += 4; + maxValue = *((DWORD*)(Code + pos)); pos += 4; + //BaseTypeAdr + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + + //If BaseTypeAdr != SelfAdr then fields extracted from BaseType + if (typeAdr != adr) + { + pos = Adr2Pos(typeAdr); + pos += 4; //SelfPointer + pos++; //typeKind + len = Code[pos]; pos++; + pos += len; //BaseClassName + pos++; //ordType + minValueB = *((DWORD*)(Code + pos)); pos += 4; + maxValueB = *((DWORD*)(Code + pos)); pos += 4; + pos += 4; //BaseClassPtr + } + else + { + minValueB = minValue; + maxValueB = maxValue; + } + + for (n = minValueB; n <= maxValueB; n++) + { + len = Code[pos]; pos++; + if (n >= minValue && n <= maxValue && n == _val) + { + return String((char*)(Code + pos), len); + } + pos += len; + } + } + //Try get from KB + else + { + uses = KnowledgeBase.GetTypeUses(TypeName.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, TypeName.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS | INFO_DUMP, &tInfo)) + { + if (tInfo.Kind == drRangeDef) + return String(Val); + //if (SameText(TypeName, tInfo.TypeName) && tInfo.Decl != "") + if (tInfo.Decl != "") + { + p = tInfo.Decl.c_str(); + e = p; + for (n = 0; n <= _val; n++) + { + b = e + 1; + e = strchr(b, ','); + if (!e) return ""; + } + return tInfo.Decl.SubString(b - p + 1, e - b); + } + } + } + } + return ""; +} +//--------------------------------------------------------------------------- +String __fastcall GetSetString(String TypeName, BYTE* ValAdr) +{ + int n, m, idx, size; + BYTE b, *pVal; + char *pDecl, *p; + WORD *uses; + MTypeInfo tInfo; + String name, result = ""; + + //Get from KB + uses = KnowledgeBase.GetTypeUses(TypeName.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, TypeName.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) + { + if (tInfo.Decl.Pos("set of ")) + { + size = tInfo.Size; + name = TrimTypeName(tInfo.Decl.SubString(8, TypeName.Length())); + uses = KnowledgeBase.GetTypeUses(name.c_str()); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, name.c_str()); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) + { + pVal = ValAdr; + pDecl = tInfo.Decl.c_str(); + p = strtok(pDecl, ",()"); + for (n = 0; n < size; n++) + { + b = *pVal; + for (m = 0; m < 8; m++) + { + if (b & ((DWORD)1 << m)) + { + if (result != "") result += ","; + if (p) + result += String(p); + else + result += "$" + Val2Str2(n * 8 + m); + } + if (p) p = strtok(0, ",)"); + } + pVal++; + } + } + } + } + } + } + if (result != "") result = "[" + result + "]"; + return result; +} +//--------------------------------------------------------------------------- +void __fastcall OutputDecompilerHeader(FILE* f) +{ + int n = sprintf(StringBuf, "IDR home page: http://kpnc.org/idr32/en"); + int m = sprintf(StringBuf, "Decompiled by IDR v.%s", IDRVersion.c_str()); + if (n < m) n = m; + + memset(StringBuf, '*', n); StringBuf[n] = 0; + fprintf(f, "//%s\n", StringBuf); + + fprintf(f, "//IDR home page: http://kpnc.org/idr32/en\n", StringBuf); + + sprintf(StringBuf, "Decompiled by IDR v.%s", IDRVersion.c_str()); + fprintf(f, "//%s\n", StringBuf); + + memset(StringBuf, '*', n); StringBuf[n] = 0; + fprintf(f, "//%s\n", StringBuf); +} +//--------------------------------------------------------------------------- +void __fastcall AddFieldXref(PFIELDINFO fInfo, DWORD ProcAdr, int ProcOfs, char type) +{ + PXrefRec recX; + + if (!fInfo->xrefs) fInfo->xrefs = new TList; + + if (!fInfo->xrefs->Count) + { + recX = new XrefRec; + recX->type = type; + recX->adr = ProcAdr; + recX->offset = ProcOfs; + fInfo->xrefs->Add((void*)recX); + return; + } + + int F = 0; + recX = (PXrefRec)fInfo->xrefs->Items[F]; + if (ProcAdr + ProcOfs < recX->adr + recX->offset) + { + recX = new XrefRec; + recX->type = type; + recX->adr = ProcAdr; + recX->offset = ProcOfs; + fInfo->xrefs->Insert(F, (void*)recX); + return; + } + int L = fInfo->xrefs->Count - 1; + recX = (PXrefRec)fInfo->xrefs->Items[L]; + if (ProcAdr + ProcOfs > recX->adr + recX->offset) + { + recX = new XrefRec; + recX->type = type; + recX->adr = ProcAdr; + recX->offset = ProcOfs; + fInfo->xrefs->Add((void*)recX); + return; + } + while (F < L) + { + int M = (F + L)/2; + recX = (PXrefRec)fInfo->xrefs->Items[M]; + if (ProcAdr + ProcOfs <= recX->adr + recX->offset) + L = M; + else + F = M + 1; + } + recX = (PXrefRec)fInfo->xrefs->Items[L]; + if (ProcAdr + ProcOfs != recX->adr + recX->offset) + { + recX = new XrefRec; + recX->type = type; + recX->adr = ProcAdr; + recX->offset = ProcOfs; + fInfo->xrefs->Insert(L, (void*)recX); + } +} +//--------------------------------------------------------------------------- +int __fastcall ArgsCmpFunction(void *item1, void *item2) +{ + PARGINFO rec1 = (PARGINFO)item1; + PARGINFO rec2 = (PARGINFO)item2; + + if (rec1->Ndx > rec2->Ndx) return 1; + if (rec1->Ndx < rec2->Ndx) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall ExportsCmpFunction(void *item1, void *item2) +{ + PExportNameRec rec1 = (PExportNameRec)item1; + PExportNameRec rec2 = (PExportNameRec)item2; + if (rec1->address > rec2->address) return 1; + if (rec1->address < rec2->address) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall ImportsCmpFunction(void *item1, void *item2) +{ + PImportNameRec rec1 = (PImportNameRec)item1; + PImportNameRec rec2 = (PImportNameRec)item2; + if (rec1->address > rec2->address) return 1; + if (rec1->address < rec2->address) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall MethodsCmpFunction(void *item1, void *item2) +{ + PMethodRec rec1 = (PMethodRec)item1; + PMethodRec rec2 = (PMethodRec)item2; + + if (rec1->kind > rec2->kind) return 1; + if (rec1->kind < rec2->kind) return -1; + if (rec1->id > rec2->id) return 1; + if (rec1->id < rec2->id) return -1; + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall AddPicode(int Pos, BYTE Op, String Name, int Ofs) +{ + if (Name == "") return; + + PInfoRec recN = GetInfoRec(Pos2Adr(Pos)); + //if (recN && recN->picode) return; + + if (!recN) + recN = new InfoRec(Pos, ikUnknown); + if (!recN->picode) + recN->picode = new PICODE; + recN->picode->Op = Op; + recN->picode->Name = Name; + if (Op == OP_CALL) + recN->picode->Ofs.Address = Ofs; + else + recN->picode->Ofs.Offset = Ofs; +} +//--------------------------------------------------------------------------- +int __fastcall SortUnitsByAdr(void *item1, void* item2) +{ + PUnitRec recU1 = (PUnitRec)item1; + PUnitRec recU2 = (PUnitRec)item2; + if (recU1->toAdr > recU2->toAdr) return 1; + if (recU1->toAdr < recU2->toAdr) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall SortUnitsByOrd(void *item1, void* item2) +{ + PUnitRec recU1 = (PUnitRec)item1; + PUnitRec recU2 = (PUnitRec)item2; + if (recU1->iniOrder > recU2->iniOrder) return 1; + if (recU1->iniOrder < recU2->iniOrder) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall SortUnitsByNam(void *item1, void* item2) +{ + PUnitRec recU1 = (PUnitRec)item1; + PUnitRec recU2 = (PUnitRec)item2; + String name1 = ""; + for (int n = 0; n < recU1->names->Count; n++) + { + if (n) name1 += "+"; + name1 += recU1->names->Strings[n]; + } + String name2 = ""; + for (int n = 0; n < recU2->names->Count; n++) + { + if (n) name2 += "+"; + name2 += recU2->names->Strings[n]; + } + int result = CompareText(name1, name2); + if (result) return result; + if (recU1->toAdr > recU2->toAdr) return 1; + if (recU1->toAdr < recU2->toAdr) return -1; + return 0; +} +//--------------------------------------------------------------------------- +String __fastcall GetArrayElementType(String arrType) +{ + DWORD adr = GetOwnTypeAdr(arrType); + if (IsValidImageAdr(adr) && IsFlagSet(cfRTTI, Adr2Pos(adr))) + return GetDynArrayTypeName(adr); + + int pos = arrType.Pos(" of "); + if (!pos) return ""; + return Trim(arrType.SubString(pos + 4, arrType.Length())); +} +//--------------------------------------------------------------------------- +int __fastcall GetArrayElementTypeSize(String arrType) +{ + String _elType; + + _elType = GetArrayElementType(arrType); + if (_elType == "") return 0; + + if (SameText(_elType, "procedure")) return 8; + return GetTypeSize(_elType); +} +//--------------------------------------------------------------------------- +//array [N1..M1,N2..M2,...,NK..MK] of Type +//A:array [N..M] of Size +//A[K]: [A + (K - N1)*Size] = [A - N1*Size + K*Size] +//A:array [N1..M1,N2..M2] of Size <=> array [N1..M1] of array [N2..M2] of Size +//A[K,L]: [A + (K - N1)*Dim2*Size + (L - N2)*Size] +//A:array [N1..M1,N2..M2,N3..M3] of Size <=> array [N1..M1] of array [N2..M2,N3..M3] of Size +//A[K,L,R]: [A + (K - N1)*Dim2*Dim3*Size + (L - N2)*Dim3*Size + (R - M3)*Size] +//A[I1,I2,...,IK]: [A + (I1 - N1L)*S/(N1H - N1L) + (I2 - N2L)*S/(N1H - N1L)*(N2H - N2L) + ... + (IK - NKL)*S/S] (*Size) +bool __fastcall GetArrayIndexes(String arrType, int ADim, int* LowIdx, int* HighIdx) +{ + char c, *p, *b; + int _dim, _val, _pos; + String _item, _item1, _item2; + + *LowIdx = 1; *HighIdx = 1;//by default + strcpy(StringBuf, arrType.c_str()); + p = strchr(StringBuf, '['); + if (!p) return false; + p++; b = p; _dim = 0; + while (1) + { + c = *p; + if (c == ',' || c == ']') + { + _dim++; + if (_dim == ADim) + { + *p = 0; + _item = String(b).Trim(); + _pos = _item.Pos(".."); + if (!_pos) + *LowIdx = 0;//Type + else + { + _item1 = _item.SubString(1, _pos - 1); + if (TryStrToInt(_item1, _val)) + *LowIdx = _val; + else + *LowIdx = 0;//Type + _item2 = _item.SubString(_pos + 2, _item.Length()); + if (TryStrToInt(_item2, _val)) + *HighIdx = _val; + else + *HighIdx = 0;//Type + } + return true; + } + if (c == ']') break; + } + p++; + } + return false; +} +//--------------------------------------------------------------------------- +int __fastcall GetArraySize(String arrType) +{ + char c, *p, *b; + int _dim, _val, _pos, _result = 1, _lIdx, _hIdx, _elTypeSize; + String _item, _item1, _item2; + + _elTypeSize = GetArrayElementTypeSize(arrType); + if (_elTypeSize == 0) return 0; + + strcpy(StringBuf, arrType.c_str()); + p = strchr(StringBuf, '['); + if (!p) return 0; + p++; b = p; _dim = 0; + while (1) + { + c = *p; + if (c == ',' || c == ']') + { + _dim++; + *p = 0; + _item = String(b).Trim(); + _pos = _item.Pos(".."); + if (!_pos) + _lIdx = 0;//Type + else + { + _item1 = _item.SubString(1, _pos - 1); + if (TryStrToInt(_item1, _val)) + _lIdx = _val; + else + _lIdx = 0;//Type + _item2 = _item.SubString(_pos + 2, _item.Length()); + if (TryStrToInt(_item2, _val)) + _hIdx = _val; + else + _hIdx = 0;//Type + } + if (_hIdx < _lIdx) return 0; + _result *= (_hIdx - _lIdx + 1); + if (c == ']') + { + _result *= _elTypeSize; + break; + } + b = p + 1; + } + p++; + } + return _result; +} +//--------------------------------------------------------------------------- +/* +String __fastcall GetArrayElement(String arrType, int offset) +{ + String _result = ""; + int _arrSize, _elTypeSize; + + _arrSize = GetArraySize(arrType); + if (_arrSize == 0) return ""; + + _elTypeSize = GetArrayElementTypeSize(arrType); + + strcpy(StringBuf, arrType.c_str()); + p = strchr(StringBuf, '['); + if (!p) return ""; + p++; b = p; _dim = 0; + while (1) + { + c = *p; + if (c == ',' || c == ']') + { + _dim++; + *p = 0; + _item = String(b).Trim(); + _pos = _item.Pos(".."); + if (!_pos) + _lIdx = 0;//Type + else + { + _item1 = _item.SubString(1, _pos - 1); + if (TryStrToInt(_item1, _val)) + _lIdx = _val; + else + _lIdx = 0;//Type + _item2 = _item.SubString(_pos + 2, _item.Length()); + if (TryStrToInt(_item2, _val)) + _hIdx = _val; + else + _hIdx = 0;//Type + } + if (_hIdx - _lIdx + 1 <= 0) return ""; + if (offset > _arrSize / (_hIdx - _lIdx + 1)) + { + + } + if (c == ']') + { + _result *= _elTypeSize; + break; + } + b = p + 1; + } + p++; + } + return _result; +} +*/ +//--------------------------------------------------------------------------- +void __fastcall Copy2Clipboard(TStrings* items, int leftMargin, bool asmCode) +{ + int n, bufLen = 0; + String line; + + Screen->Cursor = crHourGlass; + + for (n = 0; n < items->Count; n++) + { + line = items->Strings[n]; + bufLen += line.Length() + 2; + } + //Ïîñëåäíèé ñèìâîë äîëæåí áûòü 0 + bufLen++; + + if (bufLen) + { + char* buf = new char[bufLen]; + if (buf) + { + Clipboard()->Open(); + //Çàïèõèâàåì âñå äàííûå â áóôåð + char *p = buf; + for (n = 0; n < items->Count; n++) + { + line = items->Strings[n]; + p += sprintf(p, "%s", line.c_str() + leftMargin); + if (asmCode && n) p--; + *p = '\r'; p++; + *p = '\n'; p++; + } + + *p = 0; + ((TUnicodeClipboard *)Clipboard())->AsUnicodeText = buf; + Clipboard()->Close(); + + delete[] buf; + } + } + + Screen->Cursor = crDefault; +} +//--------------------------------------------------------------------------- +String __fastcall GetModuleVersion(const String& module) +{ + DWORD dwDummy; + DWORD dwFVISize = GetFileVersionInfoSize(module.c_str(), &dwDummy); + if (!dwFVISize) return ""; + + String strVersion = ""; //empty means not found, etc - some error + + LPBYTE lpVersionInfo = new BYTE[dwFVISize]; + if (GetFileVersionInfo(module.c_str(), 0, dwFVISize, lpVersionInfo)) + { + UINT uLen; + VS_FIXEDFILEINFO *lpFfi; + if (VerQueryValue(lpVersionInfo, _T("\\"), (LPVOID *)&lpFfi, &uLen)) + { + DWORD dwFileVersionMS = lpFfi->dwFileVersionMS; + DWORD dwFileVersionLS = lpFfi->dwFileVersionLS; + DWORD dwLeftMost = HIWORD(dwFileVersionMS); + DWORD dwSecondLeft = LOWORD(dwFileVersionMS); + DWORD dwSecondRight = HIWORD(dwFileVersionLS); + DWORD dwRightMost = LOWORD(dwFileVersionLS); + + strVersion.sprintf("%d.%d.%d.%d", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); + } + } + delete[] lpVersionInfo; + return strVersion; +} +//--------------------------------------------------------------------------- +bool __fastcall IsBplByExport(const char* bpl) +{ + PIMAGE_NT_HEADERS pHeader = 0; + PIMAGE_EXPORT_DIRECTORY pExport = 0; + DWORD *pFuncNames = 0; + WORD *pFuncOrdinals = 0; + DWORD *pFuncAddr = 0; + DWORD pName = 0; + DWORD imageBase = 0; + char* szDll = 0; + bool result = 0; + bool haveInitializeFunc = false; + bool haveFinalizeFunc = false; + bool haveGetPackageInfoTableFunc = false; + + HMODULE hLib = LoadLibraryEx(bpl, 0, LOAD_LIBRARY_AS_DATAFILE); + imageBase = (DWORD)(DWORD_PTR)hLib; + + if (hLib) + { + pHeader = ImageNtHeader(hLib); + + if (pHeader && pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress && + pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) + { + pExport = (PIMAGE_EXPORT_DIRECTORY)(DWORD_PTR) + (pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + imageBase); + + szDll = (char*)(imageBase + pExport->Name); + + pFuncOrdinals =(WORD*) (imageBase + pExport->AddressOfNameOrdinals); + pFuncNames =(DWORD*)(imageBase + pExport->AddressOfNames); + pFuncAddr =(DWORD*)(imageBase + pExport->AddressOfFunctions); + + for (int i = 0; i < pExport->NumberOfFunctions; i++) + { + int index = -1; + for (int j = 0; j < pExport->NumberOfNames; j++) + { + if (pFuncOrdinals[j] == i) + { + index = j; + break; + } + } + if (index != -1) + { + pName = pFuncNames[index]; + String curFunc = String((char*)imageBase + pName); + //Every BPL has a function called @GetPackageInfoTable, Initialize and Finalize. + //lets catch it! + if (!haveInitializeFunc) haveInitializeFunc = (curFunc == "Initialize"); + if (!haveFinalizeFunc) haveFinalizeFunc = (curFunc == "Finalize"); + if (!haveGetPackageInfoTableFunc) haveGetPackageInfoTableFunc = (curFunc == "@GetPackageInfoTable"); + } + if (haveInitializeFunc && haveFinalizeFunc && haveGetPackageInfoTableFunc) break; + } + + result = haveInitializeFunc && haveFinalizeFunc; + } + FreeLibrary(hLib); + } + return result; +} +//--------------------------------------------------------------------------- +//toAdr:dec reg +int __fastcall IsInitStackViaLoop(DWORD fromAdr, DWORD toAdr) +{ + int stackSize = 0; + DWORD dd, curAdr; + int instrLen; + DISINFO _disInfo; + + curAdr = fromAdr; + while (curAdr <= toAdr) + { + instrLen = Disasm.Disassemble(curAdr, &_disInfo, 0); + //if (!instrLen) return 0; + if (!instrLen) + { + curAdr++; + continue; + } + dd = *((DWORD*)_disInfo.Mnem); + //push ... + if (dd == 'hsup') + { + stackSize += 4; + curAdr += instrLen; + continue; + } + //add esp, ... + if (dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == 20 && _disInfo.OpType[1] == otIMM) + { + if ((int)_disInfo.Immediate < 0) stackSize -= (int)_disInfo.Immediate; + curAdr += instrLen; + continue; + } + //sub esp, ... + if (dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == 20 && _disInfo.OpType[1] == otIMM) + { + if ((int)_disInfo.Immediate > 0) stackSize += (int)_disInfo.Immediate; + curAdr += instrLen; + continue; + } + //dec + if (dd == 'ced') + { + curAdr += instrLen; + if (curAdr == toAdr) return stackSize; + } + break; + } + return 0; +} +//--------------------------------------------------------------------------- +int IdxToIdx32Tab[24] = { +16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 20, 21, 22, 23, 16, 17, 18, 19, 20, 21, 22, 23 +}; +int __fastcall GetReg32Idx(int Idx) +{ + return IdxToIdx32Tab[Idx]; +} +//--------------------------------------------------------------------------- +bool __fastcall IsSameRegister(int Idx1, int Idx2) +{ + return (GetReg32Idx(Idx1) == GetReg32Idx(Idx2)); +} +//--------------------------------------------------------------------------- +//Is register al, ah, ax, eax, dl, dh, dx, edx, cl, ch, cx, ecx +bool __fastcall IsADC(int Idx) +{ + int _idx = GetReg32Idx(Idx); + return (_idx == 16 || _idx == 17 || _idx == 18); +} +//--------------------------------------------------------------------------- +bool __fastcall IsAnalyzedAdr(DWORD Adr) +{ + bool analyze = false; + for (int n = 0; n < SegmentList->Count; n++) + { + PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; + if (segInfo->Start <= Adr && Adr < segInfo->Start + segInfo->Size) + { + if (!(segInfo->Flags & 0x80000)) analyze = true; + break; + } + } + return analyze; +} +//--------------------------------------------------------------------------- +//Check that fromAdr is BoundErr sequence +int __fastcall IsBoundErr(DWORD fromAdr) +{ + int _pos, _instrLen; + DWORD _adr; + PInfoRec _recN; + DISINFO _disInfo; + + _pos = Adr2Pos(fromAdr); _adr = fromAdr; + while (IsFlagSet(cfSkip, _pos)) + { + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + _adr += _instrLen; + if (_disInfo.Call && IsValidImageAdr(_disInfo.Immediate)) + { + _recN = GetInfoRec(_disInfo.Immediate); + if (_recN->SameName("@BoundErr")) return _adr - fromAdr; + } + _pos += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +bool __fastcall IsConnected(DWORD fromAdr, DWORD toAdr) +{ + int n, _pos, _instrLen; + DWORD _adr; + DISINFO _disInfo; + + _pos = Adr2Pos(fromAdr); _adr = fromAdr; + for (n = 0; n < 32; n++) + { + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + if (_disInfo.Conditional && _disInfo.Immediate == toAdr) return true; + _pos += _instrLen; _adr += _instrLen; + } + return false; +} +//--------------------------------------------------------------------------- +//Check that fromAdr points to Exit +bool __fastcall IsExit(DWORD fromAdr) +{ + BYTE _op; + int _pos, _instrLen; + DWORD _adr; + DISINFO _disInfo; + + if (!IsValidCodeAdr(fromAdr)) return 0; + _pos = Adr2Pos(fromAdr); _adr = fromAdr; + + while (1) + { + if (!IsFlagSet(cfFinally | cfExcept, _pos)) break; + _pos += 8; _adr += 8; + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_PUSH || _op == OP_JMP) + { + _adr = _disInfo.Immediate; + _pos = Adr2Pos(_adr); + } + else + { + return false; + } + } + while (1) + { + _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); + if (_disInfo.Ret) return true; + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_POP) + { + _pos += _instrLen; + _adr += _instrLen; + continue; + } + if (_op == OP_MOV && _disInfo.OpType[0] == otREG && + (IsSameRegister(_disInfo.OpRegIdx[0], 16) || IsSameRegister(_disInfo.OpRegIdx[0], 20))) + { + _pos += _instrLen; + _adr += _instrLen; + continue; + } + break; + } + return false; +} +//--------------------------------------------------------------------------- +DWORD __fastcall IsGeneralCase(DWORD fromAdr, int retAdr) +{ + int _regIdx = -1, _pos; + DWORD _dd; + DWORD _curAdr = fromAdr, _jmpAdr = 0; + int _curPos = Adr2Pos(fromAdr); + int _len, _num1 = 0; + DISINFO _disInfo; + + if (!IsValidCodeAdr(fromAdr)) return 0; + + while (1) + { + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + //Switch at current address + if (IsFlagSet(cfSwitch, _curPos)) + { + Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'aj') + { + if (IsValidCodeAdr(_disInfo.Immediate)) + return _disInfo.Immediate; + else + return 0; + } + } + //Switch at next address + if (IsFlagSet(cfSwitch, _curPos + _len)) + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'aj') + { + if (IsValidCodeAdr(_disInfo.Immediate)) + return _disInfo.Immediate; + else + return 0; + } + } + //cmp reg, imm + if (_dd == 'pmc' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) + { + _regIdx = _disInfo.OpRegIdx[0]; + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bj' || _dd == 'gj' || _dd == 'egj') + { + if (IsGeneralCase(_disInfo.Immediate, retAdr)) + { + _curAdr += _len; + _curPos += _len; + + _len = Disasm.Disassemble(Code + _curPos, (__int64)(_curAdr), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + _curAdr += _len; + _curPos += _len; + //continue; + } + continue; + } + break; + } + } + //sub reg, imm; dec reg + if ((_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'ced' && _disInfo.OpType[0] == otREG)) + { + _num1++; + if (_regIdx == -1) + _regIdx = _disInfo.OpRegIdx[0]; + else if (!IsSameRegister(_regIdx, _disInfo.OpRegIdx[0])) + break; + + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bus' && IsSameRegister(_regIdx, _disInfo.OpRegIdx[0])) + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + } + if (_dd == 'bj') + { + _curAdr += _len; + _curPos += _len; + _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + _curAdr += _len; + _curPos += _len; + } + continue; + } + if (_dd == 'zj' || _dd == 'ej') + { + _pos = GetNearestUpInstruction(Adr2Pos(_disInfo.Immediate)); + Disasm.Disassemble(Code + _pos, (__int64)Pos2Adr(_pos), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'pmj') + _jmpAdr = _disInfo.Immediate; + if (_disInfo.Ret) + _jmpAdr = Pos2Adr(GetLastLocPos(retAdr)); + _curAdr += _len; + _curPos += _len; + continue; + } + if (_dd == 'znj' || _dd == 'enj') + { + if (!_jmpAdr) + { + //if only one dec or sub then it is simple if...else construction + if (_num1 == 1) return 0; + return _disInfo.Immediate; + } + if (_disInfo.Immediate == _jmpAdr) return _jmpAdr; + } + break; + } + //add reg, imm; inc reg + if ((_dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'cni' && _disInfo.OpType[0] == otREG)) + { + _num1++; + if (_regIdx == -1) + _regIdx = _disInfo.OpRegIdx[0]; + else if (!IsSameRegister(_regIdx, _disInfo.OpRegIdx[0])) + break; + + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bus') + { + _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bj') + { + _curAdr += _len; + _curPos += _len; + continue; + } + } + if (_dd == 'zj' || _dd == 'ej') + { + _curAdr += _len; + _curPos += _len; + continue; + } + break; + } + if (_dd == 'pmj') + { + if (IsValidCodeAdr(_disInfo.Immediate)) + return _disInfo.Immediate; + else + return 0; + } + break; + } + return 0; +} +//--------------------------------------------------------------------------- +//check +//xor reg, reg +//mov reg,... +bool __fastcall IsXorMayBeSkipped(DWORD fromAdr) +{ + DWORD _curAdr = fromAdr, _dd; + int _instrlen, _regIdx; + int _curPos = Adr2Pos(fromAdr); + DISINFO _disInfo; + + _instrlen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'rox' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) + { + _regIdx = _disInfo.OpRegIdx[0]; + _curPos += _instrlen; _curAdr += _instrlen; + Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'vom' && _disInfo.OpType[0] == otREG && IsSameRegister(_disInfo.OpRegIdx[0], _regIdx)) return true; + } + return false; +} +//--------------------------------------------------------------------------- +/* +String __fastcall UnmangleName(String Name) +{ + int pos; + //skip first '@' + String Result = Name.SubString(2, Name.Length()); + String LeftPart = Result; + String RightPart = ""; + + int breakPos = Result.Pos("$"); + if (breakPos) + { + if (breakPos == 1)// + LeftPart = Result.SubString(1, breakPos - 1); + RightPart = Result.SubString(breakPos + 1, Result.Length()); + } + if (*LeftPart.AnsiLastChar() == '@') + LeftPart.SetLength(LeftPart.Length() - 1); + while (1) + { + pos = LeftPart.Pos("@@"); + if (!pos) break; + LeftPart[pos + 1] = '_'; + } + int num = 0; + while (1) + { + pos = LeftPart.Pos("@"); + if (!pos) break; + LeftPart[pos] = '.'; + num++; + } + while (1) + { + pos = LeftPart.Pos("._"); + if (!pos) break; + LeftPart[pos + 1] = '@'; + } +} +*/ +//--------------------------------------------------------------------------- +//Check construction (after cdq) +//xor eax, edx +//sub eax, edx +//return bytes to skip, if Abs, else return 0 +int __fastcall IsAbs(DWORD fromAdr) +{ + int _curPos = Adr2Pos(fromAdr), _instrLen; + DWORD _dd, _curAdr = fromAdr; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'rox' && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otREG && + _disInfo.OpRegIdx[0] == 16 && + _disInfo.OpRegIdx[1] == 18) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'bus' && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otREG && + _disInfo.OpRegIdx[0] == 16 && + _disInfo.OpRegIdx[1] == 18) + { + return (_curAdr + _instrLen) - fromAdr; + } + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction +//jxx @1 +//call @IntOver +//@1: +//return bytes to skip, if @IntOver, else return 0 +int _fastcall IsIntOver(DWORD fromAdr) +{ + int _instrLen, _curPos = Adr2Pos(fromAdr); + DWORD _curAdr = fromAdr; + PInfoRec _recN; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + if (_disInfo.Branch && _disInfo.Conditional) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + if (_disInfo.Call) + { + if (IsValidCodeAdr(_disInfo.Immediate)) + { + _recN = GetInfoRec(_disInfo.Immediate); + if (_recN && _recN->SameName("@IntOver")) return (_curAdr + _instrLen) - fromAdr; + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction (test reg, reg) +//test reg, reg +//jz @1 +//mov reg, [reg-4] +//or------------------------------------------------------------------------- +//test reg, reg +//jz @1 +//sub reg, 4 +//mov reg, [reg] +int __fastcall IsInlineLengthTest(DWORD fromAdr) +{ + int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx; + DWORD _dd, _adr, _curAdr = fromAdr; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'tset' && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otREG && + _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) + { + _regIdx = _disInfo.OpRegIdx[0]; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + _adr = _disInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + //mov reg, [reg-4] + if (_dd == 'vom' && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otMEM && + _disInfo.BaseReg == _regIdx && + _disInfo.IndxReg == -1 && + _disInfo.Offset == -4) + { + if (_adr == _curAdr + _instrLen) return (_curAdr + _instrLen) - fromAdr; + } + //sub reg, 4 + if (_dd == 'bus' && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otIMM && + _disInfo.Immediate == 4) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + //mov reg, [reg] + if (_dd == 'vom' && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otMEM && + _disInfo.BaseReg == _regIdx && + _disInfo.IndxReg == -1 && + _disInfo.Offset == 0) + { + if (_adr == _curAdr + _instrLen) return (_curAdr + _instrLen) - fromAdr; + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +//cmp [lvar], 0 +//jz @1 +//mov reg, [lvar] +//sub reg, 4 +//mov reg, [reg] +//mov [lvar], reg +int __fastcall IsInlineLengthCmp(DWORD fromAdr) +{ + BYTE _op; + int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx; + int _baseReg, _offset; + DWORD _dd, _adr, _curAdr = fromAdr; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_CMP && + _disInfo.OpType[0] == otMEM && + _disInfo.OpType[1] == otIMM && + _disInfo.Immediate == 0) + { + _baseReg = _disInfo.BaseReg; + _offset = _disInfo.Offset; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'zj' || _dd == 'ej') + { + _adr = _disInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //mov reg, [lvar] + if (_op == OP_MOV && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otMEM && + _disInfo.BaseReg == _baseReg && + _disInfo.Offset == _offset) + { + _regIdx = _disInfo.OpRegIdx[0]; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //sub reg, 4 + if (_op == OP_SUB && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otIMM && + _disInfo.Immediate == 4) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //mov reg, [reg] + if (_op == OP_MOV && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otMEM && + _disInfo.BaseReg == _regIdx && + _disInfo.IndxReg == -1 && + _disInfo.Offset == 0) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + //mov [lvar], reg + if (_op == OP_MOV && + _disInfo.OpType[0] == otMEM && + _disInfo.OpType[1] == otREG && + _disInfo.BaseReg == _baseReg && + _disInfo.Offset == _offset) + { + if (_adr == _curAdr + _instrLen) return (_curAdr + _instrLen) - fromAdr; + } + } + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +//test reg, reg +//jns @1 +//add reg, (2^k - 1) +//sar reg, k +//@1 +int __fastcall IsInlineDiv(DWORD fromAdr, int* div) +{ + BYTE _op; + int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx; + DWORD _dd, _adr, _curAdr = fromAdr, _imm; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_TEST && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otREG && + _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) + { + _regIdx = _disInfo.OpRegIdx[0]; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'snj') + { + _adr = _disInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_ADD && + _disInfo.OpType[0] == otREG && + _disInfo.OpRegIdx[0] == _regIdx && + _disInfo.OpType[1] == otIMM) + { + _imm = _disInfo.Immediate + 1; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_SAR && + _disInfo.OpType[0] == otREG && + _disInfo.OpRegIdx[0] == _regIdx && + _disInfo.OpType[1] == otIMM) + { + if (((DWORD)1 << _disInfo.Immediate) == _imm) + { + *div = _imm; + return (_curAdr + _instrLen) - fromAdr; + } + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +//and reg, imm +//jns @1 +//dec reg +//or reg, imm +//inc reg +//@1 +int __fastcall IsInlineMod(DWORD fromAdr, int* mod) +{ + BYTE _op; + int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx; + DWORD _dd, _adr, _curAdr = fromAdr, _imm; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_AND && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otIMM && + (_disInfo.Immediate & 0x80000000) != 0) + { + _regIdx = _disInfo.OpRegIdx[0]; + _imm = _disInfo.Immediate & 0x7FFFFFFF; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'snj') + { + _adr = _disInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_DEC && + _disInfo.OpType[0] == otREG && + _disInfo.OpRegIdx[0] == _regIdx) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_OR && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otIMM && + _disInfo.OpRegIdx[0] == _regIdx && + _disInfo.Immediate + _imm == 0xFFFFFFFF) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_INC && + _disInfo.OpType[0] == otREG && + _disInfo.OpRegIdx[0] == _regIdx) + { + if (_adr == _curAdr + _instrLen) + { + *mod = _imm + 1; + return (_curAdr + _instrLen) - fromAdr; + } + } + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +//test reg1, reg1 +//js @1 +//@2:mov reg2, [reg3+reg1...] +//dec reg1 +//push reg2 +//jns @2 +//@1:mov reg4, esp +int __fastcall IsCopyDynArrayToStack(DWORD fromAdr) +{ + BYTE _op; + int _curPos = Adr2Pos(fromAdr), _instrLen, _reg1Idx, _reg2Idx; + DWORD _dd, _adr1, _adr2, _curAdr = fromAdr, _imm; + DISINFO _disInfo; + + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_TEST && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otREG && + _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) + { + _reg1Idx = _disInfo.OpRegIdx[0]; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'sj') + { + _adr1 = _disInfo.Immediate; + _curPos += _instrLen; _curAdr += _instrLen; + _adr2 = _curAdr; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_MOV && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otMEM) + { + _reg2Idx = _disInfo.OpRegIdx[0]; + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_DEC && + _disInfo.OpType[0] == otREG && + _disInfo.OpRegIdx[0] == _reg1Idx) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_PUSH && + _disInfo.OpType[0] == otREG && + _disInfo.OpRegIdx[0] == _reg2Idx) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _dd = *((DWORD*)_disInfo.Mnem); + if (_dd == 'snj' && _disInfo.Immediate == _adr2) + { + _curPos += _instrLen; _curAdr += _instrLen; + _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_adr1 == _curAdr && + _op == OP_MOV && + _disInfo.OpType[0] == otREG && + _disInfo.OpType[1] == otREG && + _disInfo.OpRegIdx[1] == 20)//esp + { + return (_curAdr + _instrLen) - fromAdr; + } + } + } + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall GetLastLocPos(int fromAdr) +{ + int _pos = Adr2Pos(fromAdr); + while (1) + { + if (IsFlagSet(cfLoc, _pos)) return _pos; + _pos--; + } +} +//--------------------------------------------------------------------------- +bool __fastcall IsDefaultName(String AName) +{ + for (int Idx = 0; Idx < 8; Idx++) + { + if (SameText(AName, String(Reg32Tab[Idx]))) return true; + } + if (SameText(AName.SubString(1, 5), "lvar_")) return true; + if (SameText(AName.SubString(1, 5), "gvar_")) return true; + return false; +} +//--------------------------------------------------------------------------- +int __fastcall FloatNameToFloatType(String AName) +{ + if (SameText(AName, "Single")) return FT_SINGLE; + if (SameText(AName, "Double")) return FT_DOUBLE; + if (SameText(AName, "Extended")) return FT_EXTENDED; + if (SameText(AName, "Real")) return FT_REAL; + if (SameText(AName, "Comp")) return FT_COMP; + if (SameText(AName, "Currency")) return FT_CURRENCY; + return -1; +} +//--------------------------------------------------------------------------- +String __fastcall InputDialogExec(String caption, String labelText, String text) +{ + String _result = ""; + + FInputDlg_11011981->Caption = caption; + FInputDlg_11011981->edtName->EditLabel->Caption = labelText; + FInputDlg_11011981->edtName->Text = text; + while (_result == "") + { + if (FInputDlg_11011981->ShowModal() == mrCancel) break; + _result = FInputDlg_11011981->edtName->Text.Trim(); + } + return _result; +} +//--------------------------------------------------------------------------- +String __fastcall ManualInput(DWORD procAdr, DWORD curAdr, String caption, String labelText) +{ + String _result = ""; + + FMain_11011981->ShowCode(procAdr, curAdr, FMain_11011981->lbCXrefs->ItemIndex, -1); + FInputDlg_11011981->Caption = caption; + FInputDlg_11011981->edtName->EditLabel->Caption = labelText; + FInputDlg_11011981->edtName->Text = ""; + while (_result == "") + { + if (FInputDlg_11011981->ShowModal() == mrCancel) break; + _result = FInputDlg_11011981->edtName->Text.Trim(); + } + return _result; +} +//--------------------------------------------------------------------------- +bool __fastcall MatchCode(BYTE* code, MProcInfo* pInfo) +{ + if (!code || !pInfo) return false; + + DWORD _dumpSz = pInfo->DumpSz; + //ret + if (_dumpSz < 2) return false; + + BYTE *_dump = pInfo->Dump; + BYTE *_relocs = _dump + _dumpSz; + //jmp XXXXXXXX + if (_dumpSz == 5 && _dump[0] == 0xE9 && _relocs[1] == 0xFF) return false; + //call XXXXXXXX ret + if (_dumpSz == 6 && _dump[0] == 0xE8 && _relocs[1] == 0xFF && _dump[5] == 0xC3) return false; + + for (int n = 0; n < _dumpSz;) + { + //Relos skip + if (_relocs[n] == 0xFF) + { + n += 4; + continue; + } + if (code[n] != _dump[n]) + return false; + + n++; + } + + return true; +} +//--------------------------------------------------------------------------- +TColor SavedPenColor; +TColor SavedBrushColor; +TColor SavedFontColor; +TBrushStyle SavedBrushStyle; +//--------------------------------------------------------------------------- +void __fastcall SaveCanvas(TCanvas* ACanvas) +{ + SavedPenColor = ACanvas->Pen->Color; + SavedBrushColor = ACanvas->Brush->Color; + SavedFontColor = ACanvas->Font->Color; + SavedBrushStyle = ACanvas->Brush->Style; +} +//--------------------------------------------------------------------------- +void __fastcall RestoreCanvas(TCanvas* ACanvas) +{ + ACanvas->Pen->Color = SavedPenColor; + ACanvas->Brush->Color = SavedBrushColor; + ACanvas->Font->Color = SavedFontColor; + ACanvas->Brush->Style = SavedBrushStyle; +} +//--------------------------------------------------------------------------- +void __fastcall DrawOneItem(String AItem, TCanvas* ACanvas, TRect &ARect, TColor AColor, int flags) +{ + SaveCanvas(ACanvas); + ARect.Left = ARect.Right; + ARect.Right += ACanvas->TextWidth(AItem); + TRect R1 = Rect(ARect.Left -1, ARect.Top, ARect.Right, ARect.Bottom - 1); + if (SameText(AItem, SelectedAsmItem)) + { + ACanvas->Brush->Color = TColor(0x80DDFF); + ACanvas->Brush->Style = bsSolid; + ACanvas->FillRect(R1); + ACanvas->Brush->Style = bsClear; + ACanvas->Pen->Color = TColor(0x226DA8);; + ACanvas->Rectangle(R1); + } + ACanvas->Font->Color = AColor; + ACanvas->TextOut(ARect.Left, ARect.Top, AItem); + RestoreCanvas(ACanvas); +} +//--------------------------------------------------------------------------- +//Check try construction +//xor reg, reg +//push ebp +//push XXXXXXXX +//push fs:[reg] +//mov fs:[reg], esp +int __fastcall IsTryBegin(DWORD fromAdr, DWORD *endAdr) +{ + BYTE _op; + int _instrLen, n; + DWORD _curAdr, _endAdr; + DISINFO _disInfo; + + _curAdr = fromAdr; + for (n = 1; n <= 5; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1) + { + if (!(_op == OP_XOR && _disInfo.OpType[0] == _disInfo.OpType[1] && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1])) break; + } + else if (n == 2) + { + if (!(_op == OP_PUSH && _disInfo.OpRegIdx[0] == 21)) break; + } + else if (n == 3) + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otIMM)) break; + _endAdr = _disInfo.Immediate; + } + else if (n == 4) + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) break; + } + else if (n == 5) + { + if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) break; + *endAdr = _endAdr; + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check try construction (Delphi3:Atlantis.exe at 0x50D676) +//push ebp +//push XXXXXXXX +//push fs:[0] +//mov fs:[0], esp +int __fastcall IsTryBegin0(DWORD fromAdr, DWORD *endAdr) +{ + BYTE _op; + int _instrLen, n; + DWORD _curAdr, _endAdr; + DISINFO _disInfo; + + _curAdr = fromAdr; + for (n = 1; n <= 4; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1) + { + if (!(_op == OP_PUSH && _disInfo.OpRegIdx[0] == 21)) break; + } + else if (n == 2) + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otIMM)) break; + _endAdr = _disInfo.Immediate; + } + else if (n == 3) + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg == -1 && _disInfo.Offset == 0)) break; + } + else if (n == 4) + { + if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg == -1 && _disInfo.Offset == 0)) break; + *endAdr = _endAdr; + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check finally construction +//xor reg,reg +//pop reg +//pop reg +//pop reg +//mov fs:[reg],reg +//push XXXXXXXX +int __fastcall IsTryEndPush(DWORD fromAdr, DWORD* endAdr) +{ + BYTE _op; + int _instrLen, n; + DWORD _curAdr; + DISINFO _disInfo; + + _curAdr = fromAdr; + for (n = 1; n <= 6; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1) + { + if (!(_op == OP_XOR && _disInfo.OpType[0] == _disInfo.OpType[1] && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1])) break; + } + else if (n >= 2 && n <= 4) + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (n == 5) + { + if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) break; + } + else if (n == 6) + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otIMM)) break; + *endAdr = _disInfo.Immediate; + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check finally construction +//xor reg,reg +//pop reg +//pop reg +//pop reg +//mov fs:[reg],reg +//jmp XXXXXXXX +int __fastcall IsTryEndJump(DWORD fromAdr, DWORD* endAdr) +{ + BYTE _op; + int _instrLen, n; + DWORD _curAdr; + DISINFO _disInfo; + + _curAdr = fromAdr; + for (n = 1; n <= 6; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1) + { + if (!(_op == OP_XOR && _disInfo.OpType[0] == _disInfo.OpType[1] && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1])) break; + } + else if (n >= 2 && n <= 4) + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (n == 5) + { + if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) break; + } + else if (n == 6) + { + if (!(_op == OP_JMP && _disInfo.OpType[0] == otIMM)) break; + *endAdr = _disInfo.Immediate; + return _curAdr - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction equality ((Int64)val = XXX) +//cmp XXX,XXX -> set cfSkip (_skipAdr1 = address of this instruction) +//jne @1 -> set cfSkip (_skipAdr2 = address of this instruction) +//cmp XXX,XXX +//jne @1 +//... +//@1: +int __fastcall ProcessInt64Equality(DWORD fromAdr, DWORD* maxAdr) +{ + BYTE _op, _b; + int _instrLen, n, _curPos; + DWORD _curAdr, _adr1, _maxAdr; + DWORD _skipAdr1, _skipAdr2; + DISINFO _disInfo; + + _curAdr = fromAdr; _curPos = Adr2Pos(_curAdr); _maxAdr = 0; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + + _b = *(Code + _curPos); + if (_b == 0xF) _b = *(Code + _curPos + 1); + _b = (_b & 0xF) + 'A'; + + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + _skipAdr1 = _curAdr; + } + else if (n == 2)//jne @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) break; + _skipAdr2 = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + if (_adr1 > _maxAdr) _maxAdr = _adr1; + } + else if (n == 3)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + } + else if (n == 4)//jne @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F' && _disInfo.Immediate == _adr1)) break; + *maxAdr = _maxAdr; + SetFlag(cfSkip, Adr2Pos(_skipAdr1)); + SetFlag(cfSkip, Adr2Pos(_skipAdr2)); + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; _curPos += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction not equality ((Int64)val <> XXX) +//cmp XXX,XXX -> set cfSkip (_skipAdr1 = address of this instruction) +//jne @1 -> set cfSkip (_skipAdr2 = address of this instruction) +//cmp XXX,XXX +//je @2 +//@1: +int __fastcall ProcessInt64NotEquality(DWORD fromAdr, DWORD* maxAdr) +{ + BYTE _op, _b; + int _instrLen, n, _curPos; + DWORD _curAdr, _adr1, _adr2, _maxAdr; + DWORD _skipAdr1, _skipAdr2; + DISINFO _disInfo; + + _curAdr = fromAdr; _curPos = Adr2Pos(_curAdr); _maxAdr = 0; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + + _b = *(Code + _curPos); + if (_b == 0xF) _b = *(Code + _curPos + 1); + _b = (_b & 0xF) + 'A'; + + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + _skipAdr1 = _curAdr; + } + else if (n == 2)//jne @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) break; + _skipAdr2 = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + if (_adr1 > _maxAdr) _maxAdr = _adr1; + } + else if (n == 3)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + } + else if (n == 4)//je @2 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'E' && _curAdr + _instrLen == _adr1)) break; + _adr2 = _disInfo.Immediate;//@2 + if (_adr2 > _maxAdr) _maxAdr = _adr2; + *maxAdr = _maxAdr; + SetFlag(cfSkip, Adr2Pos(_skipAdr1)); + SetFlag(cfSkip, Adr2Pos(_skipAdr2)); + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; _curPos += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction comparison ((Int64)val >(<) XXX) +//cmp XXX,XXX -> set cfSkip (_skipAdr1 = address of this instruction) +//jxx @1 -> set cfSkip (_skipAdr2 = address of this instruction) +//cmp XXX,XXX +//jxx @@ -> set cfSkip (_skipAdr3 = address of this instruction) +//jmp @@ set cfSkip (_skipAdr4 = address of this instruction) +//@1:jxx @@ +int __fastcall ProcessInt64Comparison(DWORD fromAdr, DWORD* maxAdr) +{ + BYTE _op; + int _instrLen, n; + DWORD _curAdr, _adr, _adr1, _maxAdr; + DWORD _skipAdr1, _skipAdr2, _skipAdr3, _skipAdr4; + DISINFO _disInfo; + + _curAdr = fromAdr; _maxAdr = 0; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + _skipAdr1 = _curAdr; + } + else if (n == 2)//jxx @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _skipAdr2 = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + if (_adr1 > _maxAdr) _maxAdr = _adr1; + } + else if (n == 3)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + } + else if (n == 4)//jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _skipAdr3 = _curAdr; + _adr = _disInfo.Immediate;//@@ + if (_adr > _maxAdr) _maxAdr = _adr; + } + else if (n == 5)//jmp @@ + { + if (!(_disInfo.Branch && !_disInfo.Conditional)) break; + _skipAdr4 = _curAdr; + _adr = _disInfo.Immediate;//@@ + if (_adr > _maxAdr) _maxAdr = _adr; + } + else if (n == 6)////@1:jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional && _curAdr == _adr1)) break; + _adr = _disInfo.Immediate;//@@ + if (_adr > _maxAdr) _maxAdr = _adr; + *maxAdr = _maxAdr; + SetFlag(cfSkip, Adr2Pos(_skipAdr1)); + SetFlag(cfSkip, Adr2Pos(_skipAdr2)); + SetFlag(cfSkip, Adr2Pos(_skipAdr3)); + SetFlag(cfSkip, Adr2Pos(_skipAdr4)); + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction comparison ((Int64)val >(<) XXX) +//push reg +//push reg +//... +//cmp XXX,[esp+4] (m-th row) set cfSkip (_skipAdr1) +//jxx @1 ->set cfSkip (_skipAdr2) +//cmp XXX,[esp] +//@1:pop reg +//pop reg +//jxx @2 +int __fastcall ProcessInt64ComparisonViaStack1(DWORD fromAdr, DWORD* maxAdr) +{ + BYTE _op; + int _instrLen, n, m, _skip, _pos; + DWORD _curAdr, _adr1, _adr2, _adr3, _maxAdr, _pushAdr; + DWORD _skipAdr1, _skipAdr2; + DISINFO _disInfo; + + _curAdr = fromAdr; m = -1; _maxAdr = 0; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + } + else if (n == 2)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + _pushAdr = _curAdr; + } + else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4)//cmp XXX,[esp+4] + { + //Find nearest up instruction "push reg" + _pos = Adr2Pos(_curAdr); + while (1) + { + _pos--; + if (_pos == fromAdr) break; + if (IsFlagSet(cfInstruction, _pos)) + { + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_PUSH) break; + } + } + if (Pos2Adr(_pos) != _pushAdr) return 0; + m = n; + _skipAdr1 = _curAdr; + } + else if (m != -1 && n == m + 1)//jxx @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _skipAdr2 = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + if (_adr1 > _maxAdr) _maxAdr = _adr1; + } + else if (m != -1 && n == m + 2)//cmp XXX,[esp] + { + if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) break; + } + else if (m != -1 && n == m + 3)//@1:pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) break; + } + else if (m != -1 && n == m + 4)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (m != -1 && n == m + 5)//jxx @2 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + *maxAdr = _maxAdr; + SetFlag(cfSkip, Adr2Pos(_skipAdr1)); + SetFlag(cfSkip, Adr2Pos(_skipAdr2)); + return _curAdr + _instrLen - fromAdr; + } + if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction comparison ((Int64)val >(<) XXX) +//push reg +//push reg +//... +//cmp XXX,[esp+4] (m-th row) set cfSkip (_skipAdr1) +//jxx @1 ->set cfSkip (_skipAdr2) +//cmp XXX,[esp] +//pop reg ->set cfSkip (_skipAdr3) +//pop reg ->set cfSkip (_skipAdr4) +//jxx @@ ->set cfSkip (_skipAdr5) +//jmp @@ ->set cfSkip (_skipAdr6) +//@1: +//pop reg +//pop reg +//jxx @2 +int __fastcall ProcessInt64ComparisonViaStack2(DWORD fromAdr, DWORD* maxAdr) +{ + BYTE _op; + int _instrLen, n, m, _skip, _pos; + DWORD _curAdr, _adr, _adr1, _adr2, _maxAdr, _pushAdr; + DWORD _skipAdr1, _skipAdr2, _skipAdr3, _skipAdr4, _skipAdr5, _skipAdr6; + DISINFO _disInfo; + + _curAdr = fromAdr; m = -1; _maxAdr = 0; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + } + else if (n == 2)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + _pushAdr = _curAdr; + } + else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4)//cmp XXX,[esp+4] + { + //Find nearest up instruction "push reg" + _pos = Adr2Pos(_curAdr); + while (1) + { + _pos--; + if (_pos == fromAdr) break; + if (IsFlagSet(cfInstruction, _pos)) + { + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_PUSH) break; + } + } + if (Pos2Adr(_pos) != _pushAdr) return 0; + m = n; + _skipAdr1 = _curAdr; + } + else if (m != -1 && n == m + 1)//jxx @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _skipAdr2 = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + if (_adr1 > _maxAdr) _maxAdr = _adr1; + } + else if (m != -1 && n == m + 2)//cmp XXX,[esp] + { + if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) break; + } + else if (m != -1 && n == m + 3)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + _skipAdr3 = _curAdr; + } + else if (m != -1 && n == m + 4)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + _skipAdr4 = _curAdr; + } + else if (m != -1 && n == m + 5)//jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _skipAdr5 = _curAdr; + _adr = _disInfo.Immediate;//@3 + if (_adr > _maxAdr) _maxAdr = _adr; + } + else if (m != -1 && n == m + 6)//jmp @@ + { + if (!(_disInfo.Branch && !_disInfo.Conditional)) break; + _skipAdr6 = _curAdr; + _adr = _disInfo.Immediate;//@2 + if (_adr > _maxAdr) _maxAdr = _adr; + } + else if (m != -1 && n == m + 7)//@1:pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) break; + } + else if (m != -1 && n == m + 8)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (m != -1 && n == m + 9)//jxx @2 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _adr2 = _disInfo.Immediate; + if (_adr2 > _maxAdr) _maxAdr = _adr2; + *maxAdr = _maxAdr; + SetFlag(cfSkip, Adr2Pos(_skipAdr1)); + SetFlag(cfSkip, Adr2Pos(_skipAdr2)); + SetFlag(cfSkip, Adr2Pos(_skipAdr3)); + SetFlag(cfSkip, Adr2Pos(_skipAdr4)); + SetFlag(cfSkip, Adr2Pos(_skipAdr5)); + SetFlag(cfSkip, Adr2Pos(_skipAdr6)); + return _curAdr + _instrLen - fromAdr; + } + if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction equality ((Int64)val = XXX) +//cmp XXX,XXX +//jne @1 (_br1Adr = address of this instruction) +//cmp XXX,XXX ->skip1 up to this instruction +//jne @1 -> skip2 up to this instruction, Result = skip2 +//... +//@1:... -> delete 1 xRef to this instruction (address = _adr1) +int __fastcall IsInt64Equality(DWORD fromAdr, int* skip1, int* skip2, bool *immVal, __int64* Val) +{ + bool _imm; + BYTE _op, _b; + int _instrLen, n, _curPos, _skip; + DWORD _curAdr, _adr1, _br1Adr; + DISINFO _disInfo; + __int64 _val1, _val2; + //PInfoRec _recN; + + _curAdr = fromAdr; _curPos = Adr2Pos(_curAdr); _imm = false; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + + _b = *(Code + _curPos); + if (_b == 0xF) _b = *(Code + _curPos + 1); + _b = (_b & 0xF) + 'A'; + + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + if (_disInfo.OpType[1] == otIMM) + { + _imm = true; + _val1 = _disInfo.Immediate; + } + } + else if (n == 2)//jne @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) break; + _br1Adr = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + } + else if (n == 3)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + *skip1 = _curAdr - fromAdr; + if (_disInfo.OpType[1] == otIMM) + { + _imm = true; + _val2 = _disInfo.Immediate; + } + } + else if (n == 4)//jne @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F' && _disInfo.Immediate == _adr1)) break; + _skip = _curAdr - fromAdr; + *skip2 = _skip; + *immVal = _imm; + if (_imm) *Val = (_val1 << 32) | _val2; + return _skip; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; _curPos += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction not equality ((Int64)val <> XXX) +//cmp XXX,XXX +//jne @1 (_br1Adr = address of this instruction) +//cmp XXX,XXX ->skip1 up to this instruction +//je @2 -> skip2 up to this instruction, Result = skip2 +//@1:... -> delete 1 xRef to this instruction (address = _adr1) +int __fastcall IsInt64NotEquality(DWORD fromAdr, int* skip1, int* skip2, bool *immVal, __int64* Val) +{ + bool _imm; + BYTE _op, _b; + int _instrLen, n, _curPos, _skip; + DWORD _curAdr, _adr1, _adr2, _br1Adr; + DISINFO _disInfo; + __int64 _val1, _val2; + //PInfoRec _recN; + + _curAdr = fromAdr; _curPos = Adr2Pos(_curAdr); _imm = false; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + + _b = *(Code + _curPos); + if (_b == 0xF) _b = *(Code + _curPos + 1); + _b = (_b & 0xF) + 'A'; + + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + if (_disInfo.OpType[1] == otIMM) + { + _imm = true; + _val1 = _disInfo.Immediate; + } + } + else if (n == 2)//jne @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) break; + _br1Adr = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + } + else if (n == 3)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + *skip1 = _curAdr - fromAdr; + if (_disInfo.OpType[1] == otIMM) + { + _imm = true; + _val2 = _disInfo.Immediate; + } + } + else if (n == 4)//je @2 + { + if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'E' && _curAdr + _instrLen == _adr1)) break; + _skip = _curAdr - fromAdr; + *skip2 = _skip; + *immVal = _imm; + if (_imm) *Val = (_val1 << 32) | _val2; + return _skip; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; _curPos += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction comparison ((Int64)val >(<) XXX) +//cmp XXX,XXX +//jxx @1 (_br1Adr = address of this instruction) +//cmp XXX,XXX ->skip1 up to this instruction +//jxx @@ (_br3Adr = address of this instruction) +//jmp @@ (_br2Adr = address of this instruction) +//@1:jxx @@ (skip2 up to this instruction, Result = skip2) +int __fastcall IsInt64Comparison(DWORD fromAdr, int* skip1, int* skip2, bool* immVal, __int64* Val) +{ + bool _imm; + BYTE _op; + int _instrLen, n, m, _skip; + __int64 _val1, _val2; + DWORD _curAdr, _adr1, _br1Adr, _br2Adr, _br3Adr; + DISINFO _disInfo; + //PInfoRec _recN; + + _curAdr = fromAdr; _imm = false; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + if (_disInfo.OpType[1] == otIMM) + { + _imm = true; + _val1 = _disInfo.Immediate; + } + } + else if (n == 2)//jxx @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _br1Adr = _curAdr; + _adr1 = _disInfo.Immediate;//@1 + } + else if (n == 3)//cmp XXX,XXX + { + if (!(_op == OP_CMP)) break; + *skip1 = _curAdr - fromAdr; + if (_disInfo.OpType[1] == otIMM) + { + _imm = true; + _val2 = _disInfo.Immediate; + } + } + else if (n == 4)//jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _br3Adr = _curAdr; + } + else if (n == 5)//jmp @@ + { + if (!(_disInfo.Branch && !_disInfo.Conditional)) break; + _br2Adr = _curAdr; + } + else if (n == 6)////@1:jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional && _curAdr == _adr1)) break; + _skip = _curAdr - fromAdr; + *skip2 = _skip; + *immVal = _imm; + if (_imm) *Val = (_val1 << 32) | _val2; + return _skip; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction comparison ((Int64)val >(<) N) +//push reg +//push reg +//... +//cmp XXX,[esp+4] (m-th row) ->Simulate upto this address +//jxx @1 +//cmp XXX,[esp] ->skip1=this position +//@1:pop reg +//pop reg +//jxx @@ ->Result +int __fastcall IsInt64ComparisonViaStack1(DWORD fromAdr, int* skip1, DWORD* simEnd) +{ + BYTE _op; + int _instrLen, n, m, _pos; + DWORD _curAdr = fromAdr, _adr1, _pushAdr; + DISINFO _disInfo; + + _curAdr = fromAdr; *skip1 = 0; *simEnd = 0; m = -1; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + } + else if (n == 2)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + _pushAdr = _curAdr; + } + else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4)//cmp XXX,[esp+4] + { + //Find nearest up instruction "push reg" + _pos = Adr2Pos(_curAdr); + while (1) + { + _pos--; + if (_pos == fromAdr) break; + if (IsFlagSet(cfInstruction, _pos)) + { + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_PUSH) break; + } + } + if (Pos2Adr(_pos) != _pushAdr) return 0; + m = n; + *simEnd = _curAdr; + } + else if (m != -1 && n == m + 1)//jxx @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _adr1 = _disInfo.Immediate;//@1 + } + else if (m != -1 && n == m + 2)//cmp XXX,[esp] + { + if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) break; + *skip1 = _curAdr - fromAdr; + } + else if (m != -1 && n == m + 3)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) break; + } + else if (m != -1 && n == m + 4)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (m != -1 && n == m + 5)//jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + return _curAdr - fromAdr; + } + if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction comparison ((Int64)val >(<) XXX) +//push reg +//push reg +//... +//cmp XXX,[esp+4] (m-th row) ->Simulate upto this address +//jxx @1 +//cmp XXX,[esp] ->skip1=this position +//pop reg +//pop reg +//jxx @@ ->skip2 +//jmp @@ +//@1: +//pop reg +//pop reg +//jxx @@ ->Result +int __fastcall IsInt64ComparisonViaStack2(DWORD fromAdr, int* skip1, int* skip2, DWORD* simEnd) +{ + BYTE _op; + int _instrLen, n, m, _pos; + DWORD _curAdr = fromAdr, _adr1, _pushAdr; + DISINFO _disInfo; + + _curAdr = fromAdr; *simEnd = 0; m = -1; + for (n = 1; n <= 1024; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + } + else if (n == 2)//push reg + { + if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) break; + _pushAdr = _curAdr; + } + else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4)//cmp XXX,[esp+4] + { + //Find nearest up instruction "push reg" + _pos = Adr2Pos(_curAdr); + while (1) + { + _pos--; + if (_pos == fromAdr) break; + if (IsFlagSet(cfInstruction, _pos)) + { + Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (_op == OP_PUSH) break; + } + } + if (Pos2Adr(_pos) != _pushAdr) return 0; + m = n; + *simEnd = _curAdr; + } + else if (m != -1 && n == m + 1)//jxx @1 + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + _adr1 = _disInfo.Immediate;//@1 + } + else if (m != -1 && n == m + 2)//cmp XXX,[esp] + { + if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) break; + *skip1 = _curAdr - fromAdr; + } + else if (m != -1 && n == m + 3)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (m != -1 && n == m + 4)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (m != -1 && n == m + 5)//jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + *skip2 = _curAdr - fromAdr; + } + else if (m != -1 && n == m + 6)//jmp @@ + { + if (!(_disInfo.Branch && !_disInfo.Conditional)) break; + } + else if (m != -1 && n == m + 7)//@1:pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) break; + } + else if (m != -1 && n == m + 8)//pop reg + { + if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) break; + } + else if (m != -1 && n == m + 9)//jxx @@ + { + if (!(_disInfo.Branch && _disInfo.Conditional)) break; + return _curAdr - fromAdr; + } + if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction +//shrd reg1,reg2,N +//shr reg2,N +int __fastcall IsInt64Shr(DWORD fromAdr) +{ + BYTE _op; + int _instrLen, n, _idx, _val; + DWORD _curAdr = fromAdr; + DISINFO _disInfo; + + for (n = 1; n <= 2; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1) + { + if (!(_op == OP_SHR && _disInfo.OpNum == 3 && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpType[2] == otIMM)) break; + _idx = _disInfo.OpRegIdx[1]; + _val = _disInfo.Immediate; + } + else if (n == 2) + { + if (!(_op == OP_SHR && _disInfo.OpNum == 2 && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM && _disInfo.OpRegIdx[0] == _idx && _disInfo.Immediate == _val)) break; + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +//Check construction +//shld reg1,reg2,N +//shl reg2,N +int __fastcall IsInt64Shl(DWORD fromAdr) +{ + BYTE _op; + int _instrLen, n, _idx, _val; + DWORD _curAdr = fromAdr; + DISINFO _disInfo; + + for (n = 1; n <= 2; n++) + { + _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); + _op = Disasm.GetOp(_disInfo.Mnem); + if (n == 1) + { + if (!(_op == OP_SHL && _disInfo.OpNum == 3 && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpType[2] == otIMM)) break; + _idx = _disInfo.OpRegIdx[1]; + _val = _disInfo.Immediate; + } + else if (n == 2) + { + if (!(_op == OP_SHL && _disInfo.OpNum == 2 && _disInfo.OpType[0] == otREG && _disInfo.OpType[2] == otIMM && _disInfo.OpRegIdx[0] == _idx &&_disInfo.Immediate == _val)) break; + return _curAdr + _instrLen - fromAdr; + } + if (_disInfo.Ret) return 0; + _curAdr += _instrLen; + } + return 0; +} +//--------------------------------------------------------------------------- +bool __fastcall LineContainsShadowName(String line) +{ + if (line.Pos("Enum_") || + line.Pos("Array_") || + line.Pos("DynArray_") || + line.Pos("Set_") || + line.Pos("Record_") || + line.Pos("Unknown_")) + return true; + return false; +} +//--------------------------------------------------------------------------- +int __fastcall GetAdrOfsFromShadowName(String name) +{ + int pos = name.Pos("Enum_"); + if (pos) + return pos + 5; + pos = name.Pos("DynArray_"); + if (pos) + return pos + 9; + pos = name.Pos("Array_"); + if (pos) + return pos + 6; + pos = name.Pos("Set_"); + if (pos) + return pos + 4; + pos = name.Pos("Record_"); + if (pos) + return pos + 7; + pos = name.Pos("Unknown_"); + if (pos) + return pos + 8; + return -1; +} +//--------------------------------------------------------------------------- +//Replace symbols like '<', '>', ',', '.' to 'L', 'R', 'C', 'D' +String __fastcall SanitizeName(String name) +{ + int pos; + + while (pos = name.Pos("<")) name[pos] = 'L'; + while (pos = name.Pos(">")) name[pos] = 'R'; + while (pos = name.Pos(",")) name[pos] = 'C'; + while (pos = name.Pos(".")) name[pos] = 'D'; + return name; +} +//--------------------------------------------------------------------------- +//Shadow name is name like ":1" +String __fastcall TransformShadowName(String name, BYTE typeKind, DWORD typeAdr) +{ + String prefix; + switch (typeKind) + { + case ikEnumeration: + prefix = "Enum_"; + break; + case ikArray: + prefix = "Array_"; + break; + case ikDynArray: + prefix = "DynArray_"; + break; + case ikSet: + prefix = "Set_"; + break; + case ikRecord: + prefix = "Record_"; + break; + default: + prefix = "Unknown_"; + break; + } + return prefix + Val2Str8(typeAdr);// - 4 +} +//--------------------------------------------------------------------------- +int __fastcall FieldsCmpFunction(void *item1, void *item2) +{ + PFIELDINFO rec1 = (PFIELDINFO)item1; + PFIELDINFO rec2 = (PFIELDINFO)item2; + if (rec1->Offset > rec2->Offset) return 1; + if (rec1->Offset < rec2->Offset) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall LocalsCmpFunction(void *item1, void *item2) +{ + PLOCALINFO rec1 = (PLOCALINFO)item1; + PLOCALINFO rec2 = (PLOCALINFO)item2; + + if (rec1->Ofs > rec2->Ofs) return 1; + if (rec1->Ofs < rec2->Ofs) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall FieldInfoCmpFunction(void* item1, void* item2) +{ + if (((FIELD_INFO*)item1)->Offset > ((FIELD_INFO*)item2)->Offset) + return 1; + if (((FIELD_INFO*)item1)->Offset < ((FIELD_INFO*)item2)->Offset) + return -1; + return 0; +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Libs/Misc.h b/Misc.h similarity index 78% rename from Sources/Libs/Misc.h rename to Misc.h index b99bcfd..9e3e55d 100644 --- a/Sources/Libs/Misc.h +++ b/Misc.h @@ -1,18 +1,36 @@ -// --------------------------------------------------------------------------- +//--------------------------------------------------------------------------- #ifndef MiscH #define MiscH -// --------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +#include #include "Decompiler.h" -// --------------------------------------------------------------------------- -// Float Type +//--------------------------------------------------------------------------- +//Float Type #define FT_SINGLE 1 #define FT_DOUBLE 2 #define FT_EXTENDED 3 #define FT_REAL 4 #define FT_COMP 5 #define FT_CURRENCY 6 -// --------------------------------------------------------------------------- -// global API +//--------------------------------------------------------------------------- +typedef struct +{ + int Offset; + int Size; + String Name; + String Type; +} FIELD_INFO, *PFIELD_INFO; +//Add by ZGL----------------------------------------------------------------- +class TUnicodeClipboard : public TClipboard +{ +private: + WideString __fastcall GetAsUnicodeText(); + void __fastcall SetAsUnicodeText(const WideString Value); +public: + __property WideString AsUnicodeText = {read=GetAsUnicodeText, write=SetAsUnicodeText}; +}; +//--------------------------------------------------------------------------- +//global API void __fastcall ScaleForm(TForm* AForm); int __fastcall Adr2Pos(DWORD adr); String __fastcall Val2Str0(DWORD Val); @@ -26,13 +44,11 @@ PInfoRec __fastcall AddToBSSInfos(DWORD Adr, String AName, String ATypeName); void __fastcall AddClassAdr(DWORD Adr, const String& AName); void __fastcall AddFieldXref(PFIELDINFO fInfo, DWORD ProcAdr, int ProcOfs, char type); void __fastcall AddPicode(int Pos, BYTE Op, String Name, int Ofs); -int __fastcall ArgsCmpFunction(void *item1, void *item2); int __fastcall BranchGetPrevInstructionType(DWORD fromAdr, DWORD* jmpAdr, PLoopInfo loopInfo); bool __fastcall CanReplace(const String& fromName, const String& toName); void __fastcall ClearFlag(DWORD flag, int pos); void __fastcall ClearFlags(DWORD flag, int pos, int num); void __fastcall Copy2Clipboard(TStrings* items, int leftMargin, bool asmCode); -int __fastcall ExportsCmpFunction(void *item1, void *item2); String __fastcall ExtractClassName(const String& AName); String __fastcall ExtractProcName(const String& AName); String __fastcall ExtractName(const String& AName); @@ -73,6 +89,10 @@ String __fastcall GetParentName(const String& ClassName); int __fastcall GetParentSize(DWORD Adr); int __fastcall GetProcRetBytes(MProcInfo* pInfo); int __fastcall GetProcSize(DWORD fromAdr); +int __fastcall StrGetRecordSize(String str); +int __fastcall StrGetRecordFieldOffset(String str); +String __fastcall StrGetRecordFieldName(String str); +String __fastcall StrGetRecordFieldType(String str); int __fastcall GetRecordSize(String AName); String __fastcall GetRecordFields(int AOfs, String AType); String __fastcall GetAsmRegisterName(int Idx); @@ -82,12 +102,12 @@ DWORD __fastcall GetStopAt(DWORD vmtAdr); DWORD __fastcall GetOwnTypeAdr(String AName); PTypeRec __fastcall GetOwnTypeByName(String AName); String __fastcall GetTypeDeref(String ATypeName); +BYTE __fastcall GetTypeKind(DWORD Adr); BYTE __fastcall GetTypeKind(String AName, int* size); int __fastcall GetRTTIRecordSize(DWORD adr); int __fastcall GetPackedTypeSize(String AName); String __fastcall GetTypeName(DWORD TypeAdr); int __fastcall GetTypeSize(String AName); -int __fastcall ImportsCmpFunction(void *item1, void *item2); bool __fastcall IsADC(int Idx); int __fastcall IsBoundErr(DWORD fromAdr); bool __fastcall IsConnected(DWORD fromAdr, DWORD toAdr); @@ -100,6 +120,7 @@ bool __fastcall IsInheritsByClassName(const String& Name1, const String& Name2); bool __fastcall IsInheritsByProcName(const String& Name1, const String& Name2); int __fastcall IsInitStackViaLoop(DWORD fromAdr, DWORD toAdr); bool __fastcall IsSameRegister(int Idx1, int Idx2); +int __fastcall IsCopyDynArrayToStack(DWORD fromAdr); bool __fastcall IsValidCodeAdr(DWORD Adr); bool __fastcall IsValidCString(int pos); bool __fastcall IsValidImageAdr(DWORD Adr); @@ -109,7 +130,6 @@ bool __fastcall IsValidString(int len, int pos); bool __fastcall IsXorMayBeSkipped(DWORD fromAdr); void __fastcall MakeGvar(PInfoRec recN, DWORD adr, DWORD xrefAdr); String __fastcall MakeGvarName(DWORD adr); -int __fastcall MethodsCmpFunction(void *item1, void *item2); void __fastcall OutputDecompilerHeader(FILE* f); bool __fastcall IsFlagSet(DWORD flag, int pos); void __fastcall SetFlag(DWORD flag, int pos); @@ -117,12 +137,16 @@ void __fastcall SetFlags(DWORD flag, int pos, int num); int __fastcall SortUnitsByAdr(void *item1, void* item2); int __fastcall SortUnitsByNam(void *item1, void* item2); int __fastcall SortUnitsByOrd(void *item1, void* item2); +bool __fastcall LineContainsShadowName(String line); +int __fastcall GetAdrOfsFromShadowName(String name); +String __fastcall SanitizeName(String name); +String __fastcall TransformShadowName(String name, BYTE typeKind, DWORD typeAdr); String __fastcall TransformString(char* str, int len); String __fastcall TransformUString(WORD codePage, wchar_t* data, int len); String __fastcall TrimTypeName(const String& TypeName); String __fastcall TypeKind2Name(BYTE kind); -String __fastcall UnmangleName(String Name); -// Decompiler +//String __fastcall UnmangleName(String Name); +//Decompiler int __fastcall IsAbs(DWORD fromAdr); int _fastcall IsIntOver(DWORD fromAdr); int __fastcall IsInlineLengthCmp(DWORD fromAdr); @@ -151,5 +175,17 @@ int __fastcall IsTryBegin(DWORD fromAdr, DWORD* endAdr); int __fastcall IsTryBegin0(DWORD fromAdr, DWORD* endAdr); int __fastcall IsTryEndPush(DWORD fromAdr, DWORD* endAdr); int __fastcall IsTryEndJump(DWORD fromAdr, DWORD* endAdr); -// --------------------------------------------------------------------------- -#endif + +PFIELDINFO __fastcall GetClassField(String TypeName, int Offset); +int __fastcall GetRecordField(String ARecType, int AOfs, String& name, String& type); +int __fastcall GetField(String TypeName, int Offset, String& name, String& type); + +int __fastcall ArgsCmpFunction(void *item1, void *item2); +int __fastcall ExportsCmpFunction(void *item1, void *item2); +int __fastcall FieldInfoCmpFunction(void* item1, void* item2); +int __fastcall FieldsCmpFunction(void *item1, void *item2); +int __fastcall ImportsCmpFunction(void *item1, void *item2); +int __fastcall LocalsCmpFunction(void *item1, void *item2); +int __fastcall MethodsCmpFunction(void *item1, void *item2); +//--------------------------------------------------------------------------- +#endif diff --git a/Plugins.cpp b/Plugins.cpp new file mode 100644 index 0000000..294b82b --- /dev/null +++ b/Plugins.cpp @@ -0,0 +1,117 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "Plugins.h" +#include "Misc.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" + +void (__stdcall *fnRegisterPlugIn)(LPCTSTR *); +void (__stdcall *fnAboutPlugIn)(void); + +TFPlugins *FPlugins; +//--------------------------------------------------------------------------- +__fastcall TFPlugins::TFPlugins(TComponent* Owner) + : TForm(Owner) +{ + PluginsPath = ""; + PluginName = ""; +} +//--------------------------------------------------------------------------- +void __fastcall TFPlugins::FormShow(TObject *Sender) +{ + TSearchRec sr; + + cklbPluginsList->Clear(); + if (PluginsPath != "") + { + Screen->Cursor = crHourGlass; + String curDir = GetCurrentDir(); + ChDir(PluginsPath); + if (!FindFirst("*.dll", faArchive, sr)) + { + do + { + HINSTANCE hModule = LoadLibrary(sr.Name.c_str()); + if (hModule) + { + String info = ""; + fnRegisterPlugIn = (void (__stdcall*)(LPCTSTR *))GetProcAddress(hModule, "RegisterPlugIn"); + if (fnRegisterPlugIn) + { + LPCTSTR ptr; + fnRegisterPlugIn(&ptr); + info = ptr; + } + cklbPluginsList->Items->Add(sr.Name + " - " + info); + FreeLibrary(hModule); + } + } while (!FindNext(sr)); + + FindClose(sr); + } + ChDir(curDir); + Screen->Cursor = crDefault; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFPlugins::cklbPluginsListClickCheck(TObject *Sender) +{ + if (cklbPluginsList->State[cklbPluginsList->ItemIndex]) + { + for (int n = 0; n < cklbPluginsList->Items->Count; n++) + { + cklbPluginsList->State[n] = (n == cklbPluginsList->ItemIndex); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFPlugins::cklbPluginsListDblClick(TObject *Sender) +{ + String filename = ""; + String line = cklbPluginsList->Items->Strings[cklbPluginsList->ItemIndex]; + int pos = line.Pos('-'); + if (pos > 0) filename = line.SubString(1, pos - 1).Trim(); + if (filename != "") + { + HINSTANCE hModule = LoadLibrary((PluginsPath + "\\" + filename).c_str()); + if (hModule) + { + fnAboutPlugIn = (void (__stdcall*)(void))GetProcAddress(hModule, "AboutPlugIn"); + if (fnAboutPlugIn) fnAboutPlugIn(); + FreeLibrary(hModule); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFPlugins::bOkClick(TObject *Sender) +{ + PluginName = ""; + for (int n = 0; n < cklbPluginsList->Items->Count; n++) + { + if (cklbPluginsList->State[n]) + { + String line = cklbPluginsList->Items->Strings[n]; + int pos = line.Pos('-'); + if (pos > 0) PluginName = line.SubString(1, pos - 1).Trim(); + break; + } + } + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFPlugins::bCancelClick(TObject *Sender) +{ + PluginName = ""; + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFPlugins::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/Plugins.dfm b/Plugins.dfm similarity index 88% rename from Sources/Forms/Plugins.dfm rename to Plugins.dfm index 2d8cade..b742ea7 100644 --- a/Sources/Forms/Plugins.dfm +++ b/Plugins.dfm @@ -1,9 +1,9 @@ object FPlugins: TFPlugins Left = 550 Top = 365 + Width = 548 + Height = 287 Caption = 'Plugins' - ClientHeight = 248 - ClientWidth = 532 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -19,10 +19,11 @@ object FPlugins: TFPlugins object cklbPluginsList: TCheckListBox Left = 0 Top = 0 - Width = 532 + Width = 540 Height = 209 OnClickCheck = cklbPluginsListClickCheck Align = alTop + ItemHeight = 16 TabOrder = 0 OnDblClick = cklbPluginsListDblClick end diff --git a/Plugins.h b/Plugins.h new file mode 100644 index 0000000..ccfff3e --- /dev/null +++ b/Plugins.h @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------- + +#ifndef PluginsH +#define PluginsH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFPlugins : public TForm +{ +__published: // IDE-managed Components + TCheckListBox *cklbPluginsList; + TButton *bOk; + TButton *bCancel; + void __fastcall FormShow(TObject *Sender); + void __fastcall cklbPluginsListClickCheck(TObject *Sender); + void __fastcall cklbPluginsListDblClick(TObject *Sender); + void __fastcall bOkClick(TObject *Sender); + void __fastcall bCancelClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: // User declarations +public: // User declarations + __fastcall TFPlugins(TComponent* Owner); + String PluginsPath; + String PluginName; +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFPlugins *FPlugins; +//--------------------------------------------------------------------------- +#endif diff --git a/Plugins/globals.h b/Plugins/globals.h new file mode 100644 index 0000000..5898fd0 --- /dev/null +++ b/Plugins/globals.h @@ -0,0 +1,10 @@ +// --------------------------------------------------------------------------- +// Product identifier string defines. +#define SZPLUGINNAME "Plugin for PExplorer\0" +#define SZDESCRIPTION "Plugin for loading forms from PExplorer\0" +#define SZVERSION "Version 1.0\0" +#define SZAUTHORINFO "crypto\0" +// --------------------------------------------------------------------------- + + + diff --git a/Plugins/pexforms.bpf b/Plugins/pexforms.bpf new file mode 100644 index 0000000..64a890b --- /dev/null +++ b/Plugins/pexforms.bpf @@ -0,0 +1,3 @@ +This file is used by the project manager only and should be treated like the project file + + DllMain \ No newline at end of file diff --git a/Plugins/pexforms.bpr b/Plugins/pexforms.bpr new file mode 100644 index 0000000..999f602 --- /dev/null +++ b/Plugins/pexforms.bpr @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1049 +CodePage=1251 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[Excluded Packages] +c:\program files (x86)\borland\cbuilder6\Bin\dclado60.bpl=Borland ADO DB Components +C:\Program Files (x86)\Borland\CBuilder6\Bin\dcldb60.bpl=Borland Database Components +c:\program files (x86)\borland\cbuilder6\Bin\dclqrt60.bpl=QuickReport Components +C:\WINDOWS\SysWOW64\ibevnt60.bpl=Borland Interbase Event Alerter Component +c:\program files (x86)\borland\cbuilder6\Bin\dclbde60.bpl=Borland BDE DB Components +C:\Program Files (x86)\Borland\CBuilder6\Bin\dbx60.bpl=Borland SQL Explorer UI Package +c:\program files (x86)\borland\cbuilder6\Bin\dclcds60.bpl=Borland Base Cached ClientDataset Component +C:\Program Files (x86)\Borland\CBuilder6\Bin\dclmid60.bpl=Borland MyBase DataAccess Components +c:\program files (x86)\borland\cbuilder6\Bin\dclbdecds60.bpl=Borland Local BDE ClientDataset Components +c:\program files (x86)\borland\cbuilder6\Bin\dcltee60.bpl=TeeChart Components +c:\program files (x86)\borland\cbuilder6\Bin\dcltqr60.bpl=TeeChart for QuickReport Components +c:\program files (x86)\borland\cbuilder6\Bin\dclib60.bpl=InterBase Data Access Components +c:\program files (x86)\borland\cbuilder6\Bin\dclclxdb60.bpl=Borland CLX Database Components +C:\Program Files (x86)\Borland\CBuilder6\Bin\dclclxstd60.bpl=Borland CLX Standard Components +c:\program files (x86)\borland\cbuilder6\Bin\dclact60.bpl=Borland ActionBar Components +c:\program files (x86)\borland\cbuilder6\Bin\dclnet60.bpl=Borland Internet Components +c:\program files (x86)\borland\cbuilder6\Bin\DBWEBXPRT.BPL=Borland Web Wizard Package +c:\program files (x86)\borland\cbuilder6\Bin\DCLNMF60.bpl=NetMasters Fastnet Tools +c:\program files (x86)\borland\cbuilder6\Bin\dclsoap60.bpl=Borland SOAP Components +c:\program files (x86)\borland\cbuilder6\Bin\dclite60.bpl=Borland Integrated Translation Environment +c:\program files (x86)\borland\cbuilder6\Bin\dcldbx60.bpl=Borland dbExpress Components +c:\program files (x86)\borland\cbuilder6\Bin\dcldbxcds60.bpl=Borland Local DBX ClientDataset Components + +[HistoryLists\hlIncludePath] +Count=3 +Item0=D:\PAPA\IDR\Plugins;$(BCB)\include;$(BCB)\include\vcl +Item1=Plugins;D:\LUKOIL\ЧеремуховÑкое;$(BCB)\include;$(BCB)\include\vcl +Item2=D:\LUKOIL\ЧеремуховÑкое;$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=3 +Item0=D:\PAPA\IDR\Plugins;$(BCB)\lib\obj;$(BCB)\lib +Item1=Plugins;D:\LUKOIL\ЧеремуховÑкое;$(BCB)\lib\obj;$(BCB)\lib +Item2=D:\LUKOIL\ЧеремуховÑкое;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=1 +Item0=_DEBUG + +[HistoryLists\hlIntOutputDir] +Count=2 +Item0=D:\PAPA\IDR\Plugins +Item1=D:\LUKOIL\ЧеремуховÑкое + +[HistoryLists\hlFinalOutputDir] +Count=3 +Item0=D:\PAPA\IDR\Plugins +Item1=D:\LUKOIL\ЧеремуховÑкое\ +Item2=D:\LUKOIL\ЧеремуховÑкое + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +Launcher= +UseLauncher=0 +DebugCWD= +HostApplication= +RemoteHost= +RemotePath= +RemoteLauncher= +RemoteCWD= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + +[Linker] +LibPrefix= +LibSuffix= +LibVersion= + + \ No newline at end of file diff --git a/Plugins/pexforms.dll b/Plugins/pexforms.dll new file mode 100644 index 0000000..bd7c4a9 Binary files /dev/null and b/Plugins/pexforms.dll differ diff --git a/Plugins/pexforms.lib b/Plugins/pexforms.lib new file mode 100644 index 0000000..7fec81a Binary files /dev/null and b/Plugins/pexforms.lib differ diff --git a/Plugins/pexforms.res b/Plugins/pexforms.res new file mode 100644 index 0000000..5468ae5 Binary files /dev/null and b/Plugins/pexforms.res differ diff --git a/Plugins/pexformsmain.c b/Plugins/pexformsmain.c new file mode 100644 index 0000000..ca78357 --- /dev/null +++ b/Plugins/pexformsmain.c @@ -0,0 +1,116 @@ +//--------------------------------------------------------------------------- +#include +#include "globals.h" +//--------------------------------------------------------------------------- +// Important note about DLL memory management when your DLL uses the +// static version of the RunTime Library: +// +// If your DLL exports any functions that pass String objects (or structs/ +// classes containing nested Strings) as parameter or function results, +// you will need to add the library MEMMGR.LIB to both the DLL project and +// any other projects that use the DLL. You will also need to use MEMMGR.LIB +// if any other projects which use the DLL will be performing new or delete +// operations on any non-TObject-derived classes which are exported from the +// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling +// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases, +// the file BORLNDMM.DLL should be deployed along with your DLL. +// +// To avoid using BORLNDMM.DLL, pass string information using "char *" or +// ShortString parameters. +// +// If your DLL uses the dynamic version of the RTL, you do not need to +// explicitly add MEMMGR.LIB as this will be done implicitly for you +//--------------------------------------------------------------------------- +#pragma argsused +// --------------------------------------------------------------------------- +// GLOBAL VARIABLES +LPCTSTR szPluginName = SZPLUGINNAME; + +// --------------------------------------------------------------------------- +// EXPORT FUNCTION PROTOTYPES +void __stdcall RegisterPlugIn(LPCTSTR *); +void __stdcall AboutPlugIn(void); +int __stdcall GetDstSize(BYTE* srcData, int srcSize); +boolean __stdcall Decrypt(BYTE* srcData, int srcSize, BYTE* dstData, int dstSize); + +// --------------------------------------------------------------------------- +// EXPORT FUNCTION IMPLEMENTATIONS +// --------------------------------------------------------------------------- +void __stdcall __declspec(dllexport) RegisterPlugIn(LPCTSTR *ppPluginName) +{ + *ppPluginName = szPluginName; +} +// --------------------------------------------------------------------------- +void __stdcall __declspec(dllexport) AboutPlugIn(void) +{ + TCHAR szBuffer[MAX_PATH]; + ZeroMemory(szBuffer,MAX_PATH); + wsprintf(szBuffer, TEXT("%s\r\n%s\r\nAuthor:%s"), SZDESCRIPTION, SZVERSION, SZAUTHORINFO); + MessageBox(NULL, szBuffer, TEXT("About"), MB_OK|MB_ICONINFORMATION); +} +// --------------------------------------------------------------------------- +int __stdcall __declspec(dllexport) GetDstSize(BYTE* srcData, int srcSize) +{ + return srcSize; +} +// --------------------------------------------------------------------------- +DWORD ROL(DWORD val, BYTE shift) +{ + asm + { + mov eax, [val] + mov cl, [shift] + rol eax, cl + } +} +// --------------------------------------------------------------------------- +DWORD ROR(DWORD val, BYTE shift) +{ + asm + { + mov eax, [val] + mov cl, [shift] + ror eax, cl + } +} +// --------------------------------------------------------------------------- +boolean __stdcall __declspec(dllexport) Decrypt(BYTE* srcData, int srcSize, BYTE* dstData, int dstSize) +{ + int n; + DWORD eax, ebx, edx; + + BYTE *smp = srcData + 4; + BYTE *dmp = dstData + 4; + DWORD lvar_4 = 0x136C9856; + DWORD lvar_8 = 0x9ABFB3B6; + DWORD lvar_C = 0x7F6A0DBB; + DWORD lvar_10 = 0x020F2884;//0x84280F02;//0xD8696A85; + for (n = 0; n < srcSize - 4; n++) + { + eax = ROL(lvar_4, 7); + edx = ROL(lvar_8, 27); + eax ^= edx; + lvar_4 = eax; + ebx = lvar_C; + eax ^= ebx; + ebx = ROL(ebx, eax); + eax = ROR(eax, 15); + edx ^= eax; + edx ^= ebx; + ebx = ROR(ebx, edx); + lvar_C = ebx; + lvar_8 = edx; + *dmp = lvar_4 ^ *smp ^ lvar_10; + lvar_10 = ROR(lvar_10, edx); + smp++; + dmp++; + } + memmove(dstData, "TPF0", 4); + return TRUE; +} +// --------------------------------------------------------------------------- +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) +{ + return 1; +} +// --------------------------------------------------------------------------- diff --git a/ProgressBar.cpp b/ProgressBar.cpp new file mode 100644 index 0000000..7e363f4 --- /dev/null +++ b/ProgressBar.cpp @@ -0,0 +1,61 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "ProgressBar.h" +#include "Threads.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFProgressBar *FProgressBar; +//--------------------------------------------------------------------------- +__fastcall TFProgressBar::TFProgressBar(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TFProgressBar::FormShow(TObject *Sender) +{ + pb->Position = 0; + sb->Panels->Items[0]->Text = ""; + sb->Panels->Items[1]->Text = ""; +} +//--------------------------------------------------------------------------- +void __fastcall TFProgressBar::StartProgress(String text0, String text1, int steps) +{ + pb->Min = 0; + pb->Max = steps; + pb->Step = 1; + pb->Position = 0; + pb->Update(); + sb->Panels->Items[0]->Text = text0; + sb->Panels->Items[1]->Text = text1; + sb->Update(); +} +//--------------------------------------------------------------------------- +void __fastcall TFProgressBar::wm_updAnalysisStatus(TMessage& msg) +{ + if (taStartPrBar == msg.WParam) + { + const ThreadAnalysisData* startOperation = (ThreadAnalysisData*)msg.LParam; + FProgressBar->StartProgress(startOperation ? startOperation->sbText : String(""), "", startOperation ? startOperation->pbSteps : 0); + if (startOperation) delete startOperation; + } + else if (taUpdatePrBar == msg.WParam) + { + FProgressBar->pb->StepIt(); + FProgressBar->pb->Invalidate(); + } + else if (taUpdateStBar == msg.WParam) + { + const ThreadAnalysisData* updStatusBar = (ThreadAnalysisData*)msg.LParam; + FProgressBar->sb->Panels->Items[1]->Text = updStatusBar ? updStatusBar->sbText : String("?"); + FProgressBar->sb->Invalidate(); + + if (updStatusBar) delete updStatusBar; + Application->ProcessMessages(); + } +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/ProgressBar.dfm b/ProgressBar.dfm similarity index 91% rename from Sources/Forms/ProgressBar.dfm rename to ProgressBar.dfm index a3c41b4..7cb1f34 100644 --- a/Sources/Forms/ProgressBar.dfm +++ b/ProgressBar.dfm @@ -25,6 +25,7 @@ object FProgressBar: TFProgressBar Height = 24 Align = alClient BorderWidth = 4 + Min = 0 Max = 256 Smooth = True TabOrder = 0 @@ -43,5 +44,6 @@ object FProgressBar: TFProgressBar Text = '111' Width = 280 end> + SimplePanel = False end end diff --git a/ProgressBar.h b/ProgressBar.h new file mode 100644 index 0000000..8af915f --- /dev/null +++ b/ProgressBar.h @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------- + +#ifndef ProgressBarH +#define ProgressBarH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include "Main.h" +//--------------------------------------------------------------------------- +class TFProgressBar : public TForm +{ +__published: // IDE-managed Components + TProgressBar *pb; + TStatusBar *sb; + void __fastcall FormShow(TObject *Sender); +private: // User declarations +public: // User declarations + __fastcall TFProgressBar(TComponent* Owner); + void __fastcall StartProgress(String text0, String text1, int steps); + void __fastcall wm_updAnalysisStatus(TMessage& msg); + + BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_UPDANALYSISSTATUS, TMessage, wm_updAnalysisStatus); + END_MESSAGE_MAP(TForm) +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFProgressBar *FProgressBar; +//--------------------------------------------------------------------------- +#endif diff --git a/README.md b/README.md index fd3a515..4417ed0 100644 --- a/README.md +++ b/README.md @@ -18,17 +18,17 @@ this word) pleasant. IDR make static analysis (analyzed file is not loaded to memory and executed) that allows to safely investigate viruses, trojans and other malware applications, those which executing is dangerous or is not desirable. -The program does not require any installation activity and does not do any records in Windows registry. +The program does not require any installation activity and does not create any records in Windows registry. -~~Use Borland C++ Builder 6 to build this project.~~ +Use Borland C++ Builder 6 to build this project. -**Use Embarcadero C++ Builder 10.2 Tokyo to build this project.** +IDR dont require any installations, just copy idr.exe, dis.dll, icons.dll, idr.ico and *.bin files +to IDR home directory. Message "Cannot Initialize Disasm" means that file dis.dll is absent. -# Embarcadero C++ Builder 10.2 Tokyo Version -### *State:* **Testing** -## Notes -```Bins``` directory is used for all .bin files -## To-Do List - * Make previews of forms work - * Make process dumper work - * Test all!! \ No newline at end of file +!!! +Knowledge bases for various Delphi versions can be found here (find files kb*.7z and syskb*.bin). + +TntControls can be found at https://github.com/rofl0r/TntUnicode + +!!! +In project options use build Release version with no Optimization. diff --git a/Resources.cpp b/Resources.cpp new file mode 100644 index 0000000..3fe75f1 --- /dev/null +++ b/Resources.cpp @@ -0,0 +1,1841 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Resources.h" +#include "Main.h" +#include "Misc.h" +#include "ProgressBar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +int (__stdcall *fnGetDstSize)(BYTE*, int); +boolean (__stdcall *fnDecrypt)(BYTE*, int, BYTE*, int); + +extern TResourceInfo *ResInfo; +extern DWORD CodeBase; +extern PInfoRec *Infos; + +//--------------------------------------------------------------------------- +bool ClassesRegistered = false; + +RegClassInfo RegClasses[] = +{ + //Standard + {__classid(Forms::TFrame), "TFrame"}, + {__classid(Menus::TMainMenu), "TMainMenu"}, + {__classid(Menus::TPopupMenu), "TPopupMenu"}, + {__classid(TLabel), "TLabel"}, + {__classid(TEdit), "TEdit"}, + {__classid(TLabeledEdit), "TLabeledEdit"}, + {__classid(TMemo), "TMemo"}, + {__classid(TButton), "TButton"}, + {__classid(TCheckBox), "TCheckBox"}, + {__classid(TRadioButton), "TRadioButton"}, + {__classid(TListBox), "TListBox"}, + {__classid(TComboBox), "TComboBox"}, + {__classid(TScrollBar), "TScrollBar"}, + {__classid(TGroupBox), "TGroupBox"}, + {__classid(TRadioGroup), "TRadioGroup"}, + {__classid(TPanel), "TPanel"}, + {__classid(TActionList), "TActionList"}, + {__classid(TAction), "TAction"}, + {__classid(Stdactns::TEditCut), "TEditCut"}, + {__classid(Stdactns::TEditCopy), "TEditCopy"}, + {__classid(Stdactns::TEditPaste), "TEditPaste"}, + {__classid(Stdactns::TEditSelectAll), "TEditSelectAll"}, + {__classid(Stdactns::TEditUndo), "TEditUndo"}, + {__classid(Stdactns::TEditDelete), "TEditDelete"}, + {__classid(Stdactns::TWindowClose), "TWindowClose"}, + {__classid(Stdactns::TWindowCascade), "TWindowCascade"}, + {__classid(Stdactns::TWindowTileHorizontal), "TWindowTileHorizontal"}, + {__classid(Stdactns::TWindowTileVertical), "TWindowTileVertical"}, + {__classid(Stdactns::TWindowMinimizeAll), "TWindowMinimizeAll"}, + {__classid(Stdactns::TWindowArrange), "TWindowArrange"}, + {__classid(Stdactns::THelpContents), "THelpContents"}, + {__classid(Stdactns::THelpTopicSearch), "THelpTopicSearch"}, + {__classid(Stdactns::THelpOnHelp), "THelpOnHelp"}, + {__classid(Stdactns::THelpContextAction), "THelpContextAction"}, + {__classid(Stdactns::TFileOpen), "TFileOpen"}, + {__classid(Stdactns::TFileOpenWith), "TFileOpenWith"}, + {__classid(Stdactns::TFileSaveAs), "TFileSaveAs"}, + {__classid(Stdactns::TFilePrintSetup), "TFilePrintSetup"}, + {__classid(Stdactns::TFileExit), "TFileExit"}, + {__classid(Stdactns::TSearchFind), "TSearchFind"}, + {__classid(Stdactns::TSearchReplace), "TSearchReplace"}, + {__classid(Stdactns::TSearchFindFirst), "TSearchFindFirst"}, + {__classid(Stdactns::TSearchFindNext), "TSearchFindNext"}, + {__classid(Stdactns::TFontEdit), "TFontEdit"}, + {__classid(Stdactns::TColorSelect), "TColorSelect"}, + {__classid(Stdactns::TPrintDlg), "TPrintDlg"}, + //TRichEditxxx actions? + //TListControlXXX ? + {__classid(Extactns::TOpenPicture), "TOpenPicture"}, + {__classid(Extactns::TSavePicture), "TSavePicture"}, + //Additional + {__classid(Buttons::TBitBtn), "TBitBtn"}, + {__classid(Buttons::TSpeedButton), "TSpeedButton"}, + {__classid(Mask::TMaskEdit), "TMaskEdit"}, + {__classid(Grids::TStringGrid), "TStringGrid"}, + {__classid(Grids::TDrawGrid), "TDrawGrid"}, + {__classid(Extctrls::TImage), "TImage"}, + {__classid(Graphics::TPicture), "TPicture"}, + {__classid(Graphics::TBitmap), "TBitmap"}, + {__classid(Graphics::TGraphic), "TGraphic"}, + {__classid(Graphics::TMetafile), "TMetafile"}, + {__classid(Graphics::TIcon), "TIcon"}, + + {__classid(TShape), "TShape"}, + {__classid(TBevel), "TBevel"}, + {__classid(Forms::TScrollBox), "TScrollBox"}, + {__classid(TCheckListBox), "TCheckListBox"}, + {__classid(TSplitter), "TSplitter"}, + {__classid(TStaticText), "TStaticText"}, + {__classid(TControlBar), "TControlBar"}, + {__classid(Chart::TChart), "TChart"}, + {__classid(Series::TBarSeries), "TBarSeries"}, + {__classid(Series::THorizBarSeries), "THorizBarSeries"}, + {__classid(Series::TPointSeries), "TPointSeries"}, + {__classid(Series::TAreaSeries), "TAreaSeries"}, + {__classid(Series::TLineSeries), "TLineSeries"}, + {__classid(Series::TFastLineSeries), "TFastLineSeries"}, + {__classid(Series::TPieSeries), "TPieSeries"}, + {__classid(TColorBox), "TColorBox"}, + //Win32 + {__classid(TTabControl), "TTabControl"}, + {__classid(TPageControl), "TPageControl"}, + {__classid(TTabSheet), "TTabSheet"}, + {__classid(TImageList), "TImageList"}, + {__classid(TRichEdit), "TRichEdit"}, + {__classid(TTrackBar), "TTrackBar"}, + {__classid(TProgressBar), "TProgressBar"}, + {__classid(TUpDown), "TUpDown"}, + {__classid(THotKey), "THotKey"}, + {__classid(TAnimate), "TAnimate"}, + {__classid(TDateTimePicker), "TDateTimePicker"}, + {__classid(TMonthCalendar), "TMonthCalendar"}, + {__classid(TTreeView), "TTreeView"}, + {__classid(TListView), "TListView"}, + {__classid(THeaderControl), "THeaderControl"}, + {__classid(TStatusBar), "TStatusBar"}, + {__classid(TToolBar), "TToolBar"}, + {__classid(TToolButton), "TToolButton"}, + {__classid(TCoolBar), "TCoolBar"}, + {__classid(TComboBoxEx), "TComboBoxEx"}, + {__classid(TPageScroller), "TPageScroller"}, + //System + //__classid(TPaintBox), + {__classid(TMediaPlayer), "TMediaPlayer"}, + //Win 3.1 + {__classid(Tabs::TTabSet), "TTabSet"}, + {__classid(Outline::TOutline), "TOutline"}, + {__classid(Tabnotbk::TTabbedNotebook), "TTabbedNotebook"}, + {__classid(TNotebook), "TNotebook"}, + {__classid(TPage), "TPage"}, + {__classid(THeader), "THeader"}, + {__classid(TFileListBox), "TFileListBox"}, + {__classid(TDirectoryListBox), "TDirectoryListBox"}, + {__classid(TDriveComboBox), "TDriveComboBox"}, + {__classid(TFilterComboBox), "TFilterComboBox"}, + //Samples + {__classid(TPerformanceGraph), "TPerformanceGraph"}, + {__classid(TCSpinButton), "TCSpinButton"}, + {__classid(TTimerSpeedButton), "TTimerSpeedButton"}, + {__classid(TCSpinEdit), "TCSpinEdit"}, + {__classid(TColorGrid), "TColorGrid"}, + {__classid(TCGauge), "TCGauge"}, + {__classid(TCDirectoryOutline), "TCDirectoryOutline"}, + {__classid(TCCalendar), "TCCalendar"}, + {__classid(TPie), "TPie"}, + // + {__classid(TValueListEditor), "TValueListEditor"}, + // + {__classid(IdrDfmDefaultControl), "Default"}, + {0, 0} +}; +//--------------------------------------------------------------------------- +__fastcall TDfm::TDfm() +{ + Open = 0; + Flags = 0; + ResName = ""; + Name = ""; + ClassName = ""; + MemStream = new TMemoryStream; + ParentDfm = 0; + Events = new TList; + Components = new TList; + Form = 0; + Loader = 0; +} +//--------------------------------------------------------------------------- +__fastcall TDfm::~TDfm() +{ + delete MemStream; + + int cnt = Events->Count; + for (int n = 0; n < cnt; n++) + delete (PEventInfo)Events->Items[n]; + delete Events; + + cnt = Components->Count; + for (int n = 0; n < cnt; n++) + { + PComponentInfo cInfo = (PComponentInfo)Components->Items[n]; + if (cInfo->Events) + { + for (int m = 0; m < cInfo->Events->Count; m++) + delete (PEventInfo)cInfo->Events->Items[m]; + delete cInfo->Events; + } + delete cInfo; + } + delete Components; + if (Form) delete Form; + if (Loader) delete Loader; +} +//--------------------------------------------------------------------------- +bool __fastcall TDfm::IsFormComponent(String CompName) +{ + int cnt = Components->Count; + for (int n = 0; n < cnt; n++) + { + PComponentInfo cInfo = (PComponentInfo)Components->Items[n]; + if (SameText(CompName, cInfo->Name)) return true; + } + return false; +} +//--------------------------------------------------------------------------- +__fastcall TResourceInfo::TResourceInfo() +{ + citadel = false; + Counter = 0; + hFormPlugin = 0; + FormPluginName = ""; + FormList = new TList; + Aliases = new TStringList; + + if (!ClassesRegistered) + { + for (int n = 0;; n++) + { + if (!RegClasses[n].RegClass) break; + Classes::RegisterClass(RegClasses[n].RegClass); + } + ClassesRegistered = true; + } +} +//--------------------------------------------------------------------------- +__fastcall TResourceInfo::~TResourceInfo() +{ + if (hFormPlugin) + { + FreeLibrary(hFormPlugin); + hFormPlugin = 0; + } + int cnt = FormList->Count; + for (int n = 0; n < cnt; n++) + { + TDfm* dfm = (TDfm*)FormList->Items[n]; + delete dfm; + } + + delete FormList; + delete Aliases; + +} +//--------------------------------------------------------------------------- +int __fastcall AnalyzeSection(TDfm* Dfm, TStringList* FormText, int From, PComponentInfo CInfo, int objAlign) +{ + int n, pos, align; + String componentName, componentClass, eventName, procName; + + for (n = From; n < FormText->Count; n++) + { + String line = FormText->Strings[n].Trim(); + if (line == "") continue; + align = FormText->Strings[n].Pos(line); + + if (SameText(line, "end") && align == objAlign) break; + + bool inherited = (line.Pos("inherited ") == 1); + + if (line.Pos("object ") == 1 || inherited) + { + int pos = line.Pos(":"); + int end = line.Length(); + int tmp = line.Pos(" ["); //eg: object Label1: TLabel [1] + if (tmp) end = tmp - 1; + int off = (inherited ? 10 : 7); + + //object Label1: TLabel + if (pos) + { + componentName = line.SubString(off, pos - off).Trim(); + componentClass = line.SubString(pos + 1, end - pos).Trim(); + } + //object TLabel + else + { + componentName = "_" + Val2Str4(ResInfo->Counter) + "_"; ResInfo->Counter++; + componentClass = line.SubString(off, end - off + 1).Trim(); + } + + PComponentInfo cInfo = new ComponentInfo; + cInfo->Inherit = inherited; + cInfo->HasGlyph = false; + cInfo->Name = componentName; + cInfo->ClassName = componentClass; + cInfo->Events = new TList; + + Dfm->Components->Add((void*)cInfo); + + if (ResInfo->Aliases->IndexOf(cInfo->ClassName) == -1) + ResInfo->Aliases->Add(cInfo->ClassName); + + n = AnalyzeSection(Dfm, FormText, n + 1, cInfo, align); + } + //Events begins with "On" or "Action". But events of TDataSet may begin with no these prefixes!!! + if ((pos = line.Pos("=")) != 0 && + ((line[1] == 'O' && line[2] == 'n') || (line.Pos("Action ") == 1))) + { + eventName = line.SubString(1, pos - 1).Trim(); //Include "On" + procName = line.SubString(pos + 1, line.Length() - pos).Trim(); + PEventInfo eInfo = new EventInfo; + eInfo->EventName = eventName; + eInfo->ProcName = procName; + //Form itself + if (!CInfo) + { + Dfm->Events->Add((void*)eInfo); + } + else + { + CInfo->Events->Add((void*)eInfo); + } + } + //Has property Glyph? + if (line.Pos("Glyph.Data =") == 1) + CInfo->HasGlyph = true; + } + return n; +} +//--------------------------------------------------------------------------- +bool __stdcall EnumResNameProcedure(int hModule, char* Type, char* Name, long Param) +{ + bool res; + TFilerFlags flags; + int position, srcSize, dstSize; + TDfm* dfm; + TStringList* formText; + TMemoryStream* ms; + TResourceStream* resStream; + String className, vmtName; + BYTE signature[4]; + + if (Type == RT_RCDATA || Type == RT_BITMAP) + { + resStream = new TResourceStream(hModule, Name, Type); + if (Type == RT_RCDATA) + { + ms = new TMemoryStream; + ms->LoadFromStream(resStream); + res = true; + if (ResInfo->hFormPlugin) + { + fnGetDstSize = (int (__stdcall*)(BYTE*, int))GetProcAddress(ResInfo->hFormPlugin, "GetDstSize"); + fnDecrypt = (boolean (__stdcall*)(BYTE*, int, BYTE*, int))GetProcAddress(ResInfo->hFormPlugin, "Decrypt"); + res = (fnGetDstSize && fnDecrypt); + if (res) + { + srcSize = ms->Size; + dstSize = fnGetDstSize((BYTE*)ms->Memory, srcSize); + if (srcSize != dstSize) + { + TMemoryStream *ds = new TMemoryStream; + ds->Size = dstSize; + res = fnDecrypt((BYTE*)ms->Memory, srcSize, (BYTE*)ds->Memory, dstSize); + ms->Size = dstSize; + ms->CopyFrom(ds, dstSize); + delete ds; + } + else + { + res = fnDecrypt((BYTE*)ms->Memory, srcSize, (BYTE*)ms->Memory, dstSize); + } + } + if (res) + { + BYTE *mp = (BYTE*)ms->Memory; + BYTE len = *(mp + 4); + res = (len == strlen(Name) && SameText(Name, String((char*)mp + 5, len))); + } + } + if (res) + { + ms->Seek(0, soFromBeginning); + ms->Read(signature, 4); + if (signature[0] == 'T' && signature[1] == 'P' && signature[2] == 'F' && (signature[3] >= '0' && signature[3] <= '7')) + { + if (signature[3] == '0') + { + //Äîáàâëÿåì â ñïèñîê ðåñóðñîâ + dfm = new TDfm; + dfm->ResName = Name; + dfm->MemStream = ms; + + //Analyze text representation + formText = new TStringList; + ResInfo->GetFormAsText(dfm, formText); + + String line = formText->Strings[0]; + bool inherited = (line.Pos("inherited ") == 1); + if (inherited) + dfm->Flags |= FF_INHERITED; + if (line.Pos("object ") == 1 || inherited) + { + int off = (inherited ? 10 : 7); + int pos = line.Pos(":"); + dfm->Name = line.SubString(off, pos - off).Trim(); + dfm->ClassName = line.SubString(pos + 1, line.Length() - pos).Trim(); + AnalyzeSection(dfm, formText, 1, 0, 1); + } + delete formText; + + ((TResourceInfo*)Param)->FormList->Add((void*)dfm); + } + else if (!ResInfo->citadel) + { + ShowMessage("Citadel for Delphi detected, forms cannot be loaded"); + ResInfo->citadel = true; + } + } + else + { + delete ms; + } + } + else + { + delete ms; + } + } + else if (Type == RT_BITMAP) + { + dfm = new TDfm; + dfm->ResName = Name; + dfm->MemStream->LoadFromStream(resStream); + ((TResourceInfo*)Param)->FormList->Add((void*)dfm); + } + delete resStream; + } + return true; +} +//--------------------------------------------------------------------------- +bool __fastcall TResourceInfo::EnumResources(String FileName) +{ + citadel = false; + hFormPlugin = LoadLibrary((FMain_11011981->AppDir + "Plugins\\" + FormPluginName).c_str()); + HINSTANCE hInst = LoadLibraryEx(FileName.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); + if (hInst) + { + EnumResourceNames(hInst, RT_RCDATA, (int (__stdcall*)())EnumResNameProcedure, (long)this); + FreeLibrary(hInst); + return true; + } + if (hFormPlugin) + { + FreeLibrary(hFormPlugin); + hFormPlugin = 0; + } + return false; +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::ShowResources(TListBox* ListBox) +{ + ListBox->Clear(); + + int wid, maxwid = 0; + TCanvas *canvas = ListBox->Canvas; + int cnt = FormList->Count; + for (int n = 0; n < cnt; n++) + { + TDfm *dfm = (TDfm*)FormList->Items[n]; + ListBox->Items->Add(dfm->ResName + " {" + dfm->Name + "}"); + wid = canvas->TextWidth(dfm->ResName); if (wid > maxwid) maxwid = wid; + } + ListBox->ScrollWidth = maxwid + 2; +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::GetFormAsText(TDfm* Dfm, TStrings* DstList) +{ + TMemoryStream *memStream = new TMemoryStream; + memStream->Size = Dfm->MemStream->Size; + Dfm->MemStream->Seek(0, soFromBeginning); + ObjectBinaryToText(Dfm->MemStream, memStream); + memStream->Seek(0, soFromBeginning); + DstList->LoadFromStream(memStream); + delete memStream; +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::GetBitmap(TDfm* Dfm, Graphics::TBitmap* DstBitmap) +{ + Dfm->MemStream->Seek(0, soFromBeginning); + DstBitmap->LoadFromStream(Dfm->MemStream); +} +//--------------------------------------------------------------------------- +TDfm* __fastcall TResourceInfo::GetParentDfm(TDfm* Dfm) +{ + String parentName = GetParentName(Dfm->ClassName); + int cnt = FormList->Count; + for (int n = 0; n < cnt; n++) + { + TDfm* dfm1 = (TDfm*)FormList->Items[n]; + if (SameText(dfm1->ClassName, parentName)) return dfm1; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::CloseAllForms() +{ + int cnt = FormList->Count; + for (int n = 0; n < cnt; n++) + { + TDfm* dfm = (TDfm*)FormList->Items[n]; + if (dfm->Open == 2) + { + if (dfm->Form && dfm->Form->Visible) dfm->Form->Close(); + dfm->Form = 0; + dfm->Open = 1; + } + if (dfm->Open == 1) + { + if (dfm->Loader) delete dfm->Loader; + dfm->Form = 0; + dfm->Loader = 0; + dfm->Open = 0; + } + } + + //this is a must have call! + //it removes just closed form from the Screen->Forms[] list! + //and we'll not have a new form with name [old_name]_1 ! + Application->ProcessMessages(); +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::ReopenAllForms() +{ + int cnt = FormList->Count; + for (int n = 0; n < cnt; n++) + { + TDfm* dfm = (TDfm*)FormList->Items[n]; + if (dfm->Open == 2) //still opened + { + if (dfm->Form && dfm->Form->Visible) + { + String FormName = dfm->Form->Name; + dfm->Form->Close(); + + //this is a must have call! + //it removes just closed form from the Screen->Forms[] list! + //and we'll not have a new form with name [old_name]_1 ! + Application->ProcessMessages(); + + int frmIdx = -1; + TDfm* dfm = GetFormIdx(FormName, &frmIdx); + FMain_11011981->ShowDfm(dfm); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::InitAliases() +{ + //return; + int cnt = Aliases->Count; + for (int n = 0; n < cnt; n++) + { + String className = Aliases->Strings[n]; + if (!className.Pos("=")) + { + String alias = ""; + try + { + TMetaClass *componentClass = FindClass(className); + } + catch (Exception& e) + { + if (SameText(className, "TDBGrid")) + alias = "TStringGrid"; + else if (SameText(className, "TDBText")) + alias = "TLabel"; + else if (SameText(className, "TDBEdit")) + alias = "TEdit"; + else if (SameText(className, "TDBMemo")) + alias = "TMemo"; + else if (SameText(className, "TDBImage")) + alias = "TImage"; + else if (SameText(className, "TDBListBox")) + alias = "TListBox"; + else if (SameText(className, "TDBComboBox")) + alias = "TComboBox"; + else if (SameText(className, "TDBCheckBox")) + alias = "TCheckBox"; + else if (SameText(className, "TDBRadioGroup")) + alias = "TRadioGroup"; + else if (SameText(className, "TDBLookupListBox")) + alias = "TListBox"; + else if (SameText(className, "TDBLookupComboBox")) + alias = "TComboBox"; + else if (SameText(className, "TDBRichEdit")) + alias = "TRichEdit"; + else if (SameText(className, "TDBCtrlGrid")) + alias = "TStringGrid"; + else if (SameText(className, "TDBChart")) + alias = "TChart"; + //sample components are redirected to TCxxx components + else if (SameText(className, "TGauge")) + alias = "TCGauge"; + else if (SameText(className, "TSpinEdit")) + alias = "TCSpinEdit"; + else if (SameText(className, "TSpinButton")) + alias = "TCSpinButton"; + else if (SameText(className, "TCalendar")) + alias = "TCCalendar"; + else if (SameText(className, "TDirectoryOutline")) + alias = "TCDirectoryOutline"; + else if (SameText(className, "TShellImageList")) + alias = "TImageList"; //special case, if not handled- crash (eg:1st Autorun Express app) + else if (!GetClass(className)) + { + if (IsInheritsByClassName(className, "TBasicAction")) + alias = "TAction"; + else if (IsInheritsByClassName(className, "TMainMenu")) + alias = "TMainMenu"; + else if (IsInheritsByClassName(className, "TPopupMenu")) + alias = "TPopupMenu"; + else if (IsInheritsByClassName(className, "TCustomLabel") + || AnsiContainsText (className, "Label") //evristika + ) + alias = "TLabel"; + else if (IsInheritsByClassName(className, "TCustomEdit")) + alias = "TEdit"; + else if (IsInheritsByClassName(className, "TCustomMemo")) + alias = "TMemo"; + else if (IsInheritsByClassName(className, "TButton")) + alias = "TButton"; + else if (IsInheritsByClassName(className, "TCustomCheckBox")) + alias = "TCheckBox"; + else if (IsInheritsByClassName(className, "TRadioButton")) + alias = "TRadioButton"; + else if (IsInheritsByClassName(className, "TCustomListBox")) + alias = "TListBox"; + else if (IsInheritsByClassName(className, "TCustomComboBox")) + alias = "TComboBox"; + else if (IsInheritsByClassName(className, "TCustomGroupBox")) + alias = "TGroupBox"; + else if (IsInheritsByClassName(className, "TCustomRadioGroup")) + alias = "TRadioGroup"; + else if (IsInheritsByClassName(className, "TCustomPanel")) + alias = "TPanel"; + else if (IsInheritsByClassName(className, "TBitBtn")) + alias = "TBitBtn"; + else if (IsInheritsByClassName(className, "TSpeedButton")) + alias = "TSpeedButton"; + else if (IsInheritsByClassName(className, "TImage")) + alias = "TImage"; + else if (IsInheritsByClassName(className, "TImageList")) + alias = "TImageList"; + else if (IsInheritsByClassName(className, "TBevel")) + alias = "TBevel"; + else if (IsInheritsByClassName(className, "TSplitter")) + alias = "TSplitter"; + else if (IsInheritsByClassName(className, "TPageControl")) + alias = "TPageControl"; + else if (IsInheritsByClassName(className, "TToolBar")) + alias = "TToolBar"; + else if (IsInheritsByClassName(className, "TToolButton")) + alias = "TToolButton"; + else if (IsInheritsByClassName(className, "TCustomStatusBar")) + alias = "TStatusBar"; + else if (IsInheritsByClassName(className, "TDateTimePicker")) + alias = "TDateTimePicker"; + else if (IsInheritsByClassName(className, "TCustomListView")) + alias = "TListView"; + else if (IsInheritsByClassName(className, "TCustomTreeView")) + alias = "TTreeView"; + else + alias = "Default"; + } + } + if (alias != "") + Aliases->Strings[n] = className + "=" + alias; + } + } +} +//--------------------------------------------------------------------------- +String __fastcall TResourceInfo::GetAlias(String ClassName) +{ + for (int n = 0; n < Aliases->Count; n++) + { + if (SameText(ClassName, Aliases->Names[n])) + return Aliases->Values[ClassName]; + } + return ""; +} +//--------------------------------------------------------------------------- +TDfm* __fastcall TResourceInfo::GetFormIdx(String FormName, int* idx) +{ + for (int n = 0; n < FormList->Count; n++) + { + TDfm* dfm = (TDfm*)FormList->Items[n]; + //Find form + if (SameText(dfm->Name, FormName)) + { + *idx = n; + return dfm; + } + } + *idx = -1; + return 0; +} +//--------------------------------------------------------------------------- +TDfm* __fastcall TResourceInfo::GetFormByClassName(String ClassName) +{ + for (int n = 0; n < FormList->Count; n++) + { + TDfm* dfm = (TDfm*)FormList->Items[n]; + //Find form + if (SameText(dfm->ClassName, ClassName)) return dfm; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TResourceInfo::GetEventsList(String FormName, TList* Lst) +{ + int n, evCnt, evCnt1, compCnt, compCnt1, frmCnt; + PEventListItem item; + PInfoRec recN, recN1; + + TDfm* dfm = GetFormIdx(FormName, &n); + if (!dfm) return; + + DWORD classAdr = GetClassAdr(dfm->ClassName); + recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; + //Form + //Inherited - begin fill list + if (dfm->Flags & FF_INHERITED) + { + TDfm* parentDfm = GetParentDfm(dfm); + if (parentDfm) + { + GetEventsList(parentDfm->Name, Lst); + int evCount = Lst->Count; + evCount = evCount; + } + } + if (dfm->Events->Count) + { + TList* ev = dfm->Events; + evCnt = ev->Count; + for (int k = 0; k < evCnt; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + item = new EventListItem; + item->CompName = FormName; + item->EventName = eInfo->EventName;//eInfo->ProcName; + String methodName = dfm->ClassName + "." + eInfo->ProcName; + //Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà + PMethodRec recM = FMain_11011981->GetMethodInfo(recN, methodName); + item->Adr = (recM) ? recM->address : 0; + Lst->Add(item); + } + } + //Components + compCnt = dfm->Components->Count; + for (int m = 0; m < compCnt; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + if (!cInfo->Events->Count) continue; + + TList* ev = cInfo->Events; + evCnt = ev->Count; + for (int k = 0; k < evCnt; k++) + { + recN1 = recN; + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + item = new EventListItem; + item->CompName = cInfo->Name; + item->EventName = eInfo->EventName;//eInfo->ProcName; + String methodName = ""; + //Action + if (SameText(eInfo->EventName, "Action")) + { + //Name eInfo->ProcName like FormName.Name + int dotpos = eInfo->ProcName.Pos("."); + if (dotpos) + { + String moduleName = eInfo->ProcName.SubString(1, dotpos - 1); + String actionName = eInfo->ProcName.SubString(dotpos + 1, eInfo->ProcName.Length() - dotpos); + //Find form moduleName + frmCnt = FormList->Count; + for (int j = 0; j < frmCnt; j++) + { + TDfm* dfm1 = (TDfm*)FormList->Items[j]; + if (SameText(dfm1->Name, moduleName)) + { + classAdr = GetClassAdr(dfm1->ClassName); + recN1 = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; + //Find component actionName + compCnt1 = dfm1->Components->Count; + for (int r = 0; r < compCnt1; r++) + { + PComponentInfo cInfo1 = (PComponentInfo)dfm1->Components->Items[r]; + if (SameText(cInfo1->Name, actionName)) + { + //Find event OnExecute + TList* ev1 = cInfo1->Events; + evCnt1 = ev1->Count; + for (int i = 0; i < evCnt1; i++) + { + PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; + if (SameText(eInfo1->EventName, "OnExecute")) + { + methodName = dfm1->ClassName + "." + eInfo1->ProcName; + break; + } + } + break; + } + } + break; + } + } + } + else + { + //Find component eInfo->ProcName + compCnt = dfm->Components->Count; + for (int r = 0; r < compCnt; r++) + { + PComponentInfo cInfo1 = (PComponentInfo)dfm->Components->Items[r]; + if (SameText(cInfo1->Name, eInfo->ProcName)) + { + //Find event OnExecute + TList* ev1 = cInfo1->Events; + evCnt1 = ev1->Count; + for (int i = 0; i < evCnt1; i++) + { + PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; + if (SameText(eInfo1->EventName, "OnExecute")) + { + methodName = dfm->ClassName + "." + eInfo1->ProcName; + break; + } + } + break; + } + } + } + } + else + { + methodName = dfm->ClassName + "." + eInfo->ProcName; + } + //Find method address + PMethodRec recM = FMain_11011981->GetMethodInfo(recN1, methodName); + item->Adr = (recM) ? recM->address : 0; + Lst->Add(item); + } + } +} +//--------------------------------------------------------------------------- +//IdrDfmReader +//--------------------------------------------------------------------------- +__fastcall IdrDfmReader::IdrDfmReader(TStream* Stream, int BufSize) :TReader(Stream, BufSize) +{ +} +//--------------------------------------------------------------------------- +//TComponentEvents +//--------------------------------------------------------------------------- +__fastcall TComponentEvents::TComponentEvents(TCollection* Owner) : TCollectionItem(Owner) +{ + Component = 0; + FoundEvents = new TStringList(); + FoundEvents->Sorted = true; +} +//--------------------------------------------------------------------------- +__fastcall TComponentEvents::~TComponentEvents() +{ + delete FoundEvents; +} +//--------------------------------------------------------------------------- +//IdrDfmForm +//--------------------------------------------------------------------------- +__fastcall IdrDfmForm::IdrDfmForm(TComponent* Owner) : TForm(Owner) +{ + compsEventsList = 0; + current = 0; + evPopup = new TPopupMenu(0); + evPopup->AutoPopup = false; + evPopup->AutoHotkeys = maManual; + frmTree = 0; + + KeyPreview = true; +} +//--------------------------------------------------------------------------- +__fastcall IdrDfmForm::IdrDfmForm(TComponent* Owner, int Dummy) : TForm(Owner, Dummy) +{ + compsEventsList = 0; + current = 0; + evPopup = new TPopupMenu(0); + evPopup->AutoPopup = false; + evPopup->AutoHotkeys = maManual; + frmTree = 0; + + KeyPreview = true; +} +//--------------------------------------------------------------------------- +__fastcall IdrDfmForm::~IdrDfmForm() +{ + if (compsEventsList) delete compsEventsList; + compsEventsList = 0; + delete evPopup; + if (frmTree) delete frmTree; + frmTree = 0; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::SetDesigning(bool value, bool SetChildren) +{ + TComponent::SetDesigning(value, SetChildren); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::CreateHandle() +{ + if (FormStyle == fsMDIChild) + { + FormStyle = fsNormal; + return; + } + + TForm::CreateHandle(); +} +//--------------------------------------------------------------------------- +//this is required action as sometimes ShortCut from target exe could be same as ours... +void __fastcall IdrDfmForm::SetupControlResetShortcut(TComponent* component) +{ + TCustomAction* action = dynamic_cast(component); + if (action && action->ShortCut) + action->ShortCut = 0; + + TMenuItem* mi = dynamic_cast(component); + if (mi && mi->ShortCut) + mi->ShortCut = 0; +} +//--------------------------------------------------------------------------- +//different fine-tuning and fixes for components of the DFM Forms +void __fastcall IdrDfmForm::SetupControls() +{ + TComponent* component = this; + TControl* control = dynamic_cast(this); + if (control) + { + SetupControlHint(Name, control, GetShortHint(control->Hint)); + ((TMyControl*)control)->OnMouseDown = ControlMouseDown; + if (((TMyControl*)control)->PopupMenu) ((TMyControl*)control)->PopupMenu = 0; + } + + TBasicAction* action = dynamic_cast(component); + if (action) action->OnExecute = ActionExecute; + SetupControlResetShortcut(component); + + for (int n = 0; n < ComponentCount; n++) + { + component = Components[n]; + const String curName = component->Name; + SetupControlResetShortcut(component); + + control = dynamic_cast(component); + if (control) + { + SetupControlHint(Name, control, GetShortHint(control->Hint)); + control->Visible = true; + control->Enabled = true; + ((TMyControl*)control)->OnMouseDown = ControlMouseDown; + if (((TMyControl*)control)->PopupMenu) ((TMyControl*)control)->PopupMenu = 0; + } + + if (TPageControl* pageControl = dynamic_cast(component)) + { + if (pageControl->PageCount > 0) + pageControl->ActivePageIndex = pageControl->PageCount - 1; + } + + else if(TTabSheet* ts = dynamic_cast(component)) + ts->TabVisible = true; + + else if (TBasicAction* action = dynamic_cast(component)) + action->OnExecute = ActionExecute; + + else if (TMenuItem* mi = dynamic_cast(component)) + { + SetupMenuItem(mi, Name); //we start from this form name + mi->Enabled = true; + } + + //else if(TProgressBar* pb = dynamic_cast(component)) + // FProgressBar->pb->Position = FProgressBar->pb->Max/3; + + //else if (TStatusBar* sb = dynamic_cast(component)) + // FProgressBar->sb->AutoHint = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::ControlMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if (Button == mbRight) + { + TControl* control = dynamic_cast(Sender); + if (control) + { + evPopup->Items->Clear(); + ShowMyPopupMenu(Name, control->Name, true); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::miClick(TObject* Sender) +{ + TMenuItem* mi = dynamic_cast(Sender); + if (mi->Tag) FMain_11011981->ShowCode(mi->Tag, 0, -1, -1); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::ActionExecute(TObject* Sender) +{ + //note: this is stub, you shold not stop here..... + //if you are here -> smth not OK + int x=10; + ++x; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::ShowMyPopupMenu(String FormName, String ControlName, bool show) +{ + int n; + TMenuItem *mi; + TDfm* dfm = ResInfo->GetFormIdx(FormName, &n); + if (!dfm) return; + + DWORD classAdr = GetClassAdr(dfm->ClassName); + PInfoRec recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; + + //Ôîðìà? + if (SameText(dfm->Name, ControlName)) + { + //Inherited - íà÷àëè çàïîëíÿòü ìåíþ + if (dfm->Flags & FF_INHERITED) + { + TDfm* parentDfm = ResInfo->GetParentDfm(dfm); + if (parentDfm) ShowMyPopupMenu(parentDfm->Name, parentDfm->Name, false); + // êîíöå äîáàâëÿåì ðàçäåëèòåëü + mi = new TMenuItem(evPopup); + mi->Caption = "-"; + evPopup->Items->Add(mi); + } + + //Ïåðâàÿ ñòðîêà ìåíþ - íàçâàíèå êîíòðîëà + mi = new TMenuItem(evPopup); + mi->Caption = dfm->Name + "." + dfm->ClassName; + mi->Tag = classAdr; + mi->OnClick = miPopupClick; + evPopup->Items->Add(mi); + //Âòîðàÿ ñòðîêà ìåíþ - ðàçäåëèòåëü + mi = new TMenuItem(evPopup); + mi->Caption = "-"; + evPopup->Items->Add(mi); + + PInfoRec recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; + + TList* ev = dfm->Events; + for (int k = 0; k < ev->Count; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + mi = new TMenuItem(evPopup); + mi->Caption = eInfo->EventName + " = " + eInfo->ProcName; + String methodName = dfm->ClassName + "." + eInfo->ProcName; + //Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà + PMethodRec recM = FMain_11011981->GetMethodInfo(recN, methodName); + mi->Tag = (recM) ? recM->address : 0; + mi->OnClick = miPopupClick; + evPopup->Items->Add(mi); + } + if (show && evPopup->Items->Count) + { + TPoint cursorPos; + GetCursorPos(&cursorPos); + evPopup->Popup(cursorPos.x, cursorPos.y); + } + return; + } + //Êîìïîíåíòà ôîðìû? + else + { + //Inherited - íà÷àëè çàïîëíÿòü ìåíþ + if (dfm->Flags & FF_INHERITED) + { + TDfm* parentDfm = ResInfo->GetParentDfm(dfm); + if (parentDfm) ShowMyPopupMenu(parentDfm->Name, ControlName, false); + // êîíöå äîáàâëÿåì ðàçäåëèòåëü + mi = new TMenuItem(evPopup); + mi->Caption = "-"; + evPopup->Items->Add(mi); + } + + for (int m = 0; m < dfm->Components->Count; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + //Íàøëè êîìïîíåíòó, êîòîðîé ïðèíàäëåæèò control + if (SameText(cInfo->Name, ControlName)) + { + //×èñòèì evPopup + evPopup->Items->Clear(); + //Ïåðâàÿ ñòðîêà ìåíþ - íàçâàíèå êîíòðîëà + mi = new TMenuItem(evPopup); + mi->Caption = cInfo->Name + "." + cInfo->ClassName; + mi->Tag = GetClassAdr(cInfo->ClassName); + mi->OnClick = miPopupClick; + evPopup->Items->Add(mi); + //Âòîðàÿ ñòðîêà ìåíþ - ðàçäåëèòåëü + mi = new TMenuItem(evPopup); + mi->Caption = "-"; + evPopup->Items->Add(mi); + + TList* ev = cInfo->Events; + for (int k = 0; k < ev->Count; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + mi = new TMenuItem(evPopup); + mi->Caption = eInfo->EventName + " = " + eInfo->ProcName; + String methodName = ""; + //Action + if (SameText(eInfo->EventName, "Action")) + { + //Èìÿ eInfo->ProcName ìîæåò èìåòü âèä FormName.Name + int dotpos = eInfo->ProcName.Pos("."); + if (dotpos) + { + String moduleName = eInfo->ProcName.SubString(1, dotpos - 1); + String actionName = eInfo->ProcName.SubString(dotpos + 1, eInfo->ProcName.Length() - dotpos); + //Èùåì ôîðìó moduleName + for (int j = 0; j < ResInfo->FormList->Count; j++) + { + TDfm* dfm1 = (TDfm*)ResInfo->FormList->Items[j]; + if (SameText(dfm1->Name, moduleName)) + { + classAdr = GetClassAdr(dfm1->ClassName); + recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; + //Èùåì êîìïîíåíòó actionName + for (int r = 0; r < dfm1->Components->Count; r++) + { + PComponentInfo cInfo1 = (PComponentInfo)dfm1->Components->Items[r]; + if (SameText(cInfo1->Name, actionName)) + { + //Èùåì ñîáûòèå OnExecute + TList* ev1 = cInfo1->Events; + for (int i = 0; i < ev1->Count; i++) + { + PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; + if (SameText(eInfo1->EventName, "OnExecute")) + { + methodName = dfm1->ClassName + "." + eInfo1->ProcName; + break; + } + } + break; + } + } + break; + } + } + } + else + { + //Èùåì êîìïîíåíòó eInfo->ProcName + for (int r = 0; r < dfm->Components->Count; r++) + { + PComponentInfo cInfo1 = (PComponentInfo)dfm->Components->Items[r]; + if (SameText(cInfo1->Name, eInfo->ProcName)) + { + //Èùåì ñîáûòèå OnExecute + TList* ev1 = cInfo1->Events; + for (int i = 0; i < ev1->Count; i++) + { + PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; + if (SameText(eInfo1->EventName, "OnExecute")) + { + methodName = dfm->ClassName + "." + eInfo1->ProcName; + break; + } + } + break; + } + } + } + } + else + { + methodName = dfm->ClassName + "." + eInfo->ProcName; + } + //Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà + PMethodRec recM = FMain_11011981->GetMethodInfo(recN, methodName); + mi->Tag = (recM) ? recM->address : 0; + mi->OnClick = miPopupClick; + evPopup->Items->Add(mi); + } + if (evPopup->Items->Count) + { + TPoint cursorPos; + GetCursorPos(&cursorPos); + evPopup->Popup(cursorPos.x, cursorPos.y); + } + return; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::miPopupClick(TObject *Sender) +{ + TMenuItem* mi = (TMenuItem*)Sender; + DWORD Adr = mi->Tag; + if (Adr && IsValidImageAdr(Adr)) + { + PInfoRec recN = GetInfoRec(Adr); + if (recN) + { + if (recN->kind == ikVMT) + FMain_11011981->ShowClassViewer(Adr); + else + FMain_11011981->ShowCode(Adr, 0, -1, -1); + } + } + else + ShowMessage("Handler not found"); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::SetupControlHint(String FormName, TControl* Control, String InitHint) +{ + for (int n = 0; n < ResInfo->FormList->Count; n++) + { + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + //Íàøëè ôîðìó, êîòîðîé ïðèíàäëåæèò control + if (SameText(dfm->Name, FormName)) + { + String hint = InitHint; + //Ñàìà ôîðìà? + if (SameText(dfm->Name, Control->Name)) + { + if (hint != "") hint += "\n"; + hint += dfm->Name + ":" + dfm->ClassName; + + TList* ev = dfm->Events; + for (int k = 0; k < ev->Count; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + hint += "\n" + eInfo->EventName + " = " + eInfo->ProcName; + } + Control->Hint = hint; + Control->ShowHint = true; + return; + } + else + { + for (int m = 0; m < dfm->Components->Count; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + //Íàøëè êîìïîíåíòó, êîòîðîé ïðèíàäëåæèò control + if (SameText(cInfo->Name, Control->Name)) + { + if (hint != "") hint += "\n"; + hint += cInfo->Name + ":" + cInfo->ClassName; + + TList* ev = cInfo->Events; + for (int k = 0; k < ev->Count; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + hint += "\n" + eInfo->EventName + " = " + eInfo->ProcName; + } + Control->Hint = hint; + Control->ShowHint = true; + return; + } + } + } + } + } +} +//--------------------------------------------------------------------------- +//find menu item handler (inherited forms supported) +void __fastcall IdrDfmForm::SetupMenuItem(TMenuItem* mi, String searchName) +{ + bool menuFound = false; + bool formInherited = false; + TDfm* curDfm = 0; + + for (int n = 0; n < ResInfo->FormList->Count; n++) + { + //as: I dont like this, maybe put TDfm* into IdrDfmForm? + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + + //Íàøëè ôîðìó, êîòîðîé ïðèíàäëåæèò control + if (SameText(dfm->Name, searchName)) + { + curDfm = dfm; + formInherited = dfm->Flags & FF_INHERITED; + + for (int m = 0; m < dfm->Components->Count; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + + //Íàøëè êîìïîíåíòó, êîòîðîé ïðèíàäëåæèò mi + if (SameText(cInfo->Name, mi->Name)) + { + DWORD classAdr = GetClassAdr(dfm->ClassName); + PInfoRec recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; + + TList* ev = cInfo->Events; + for (int k = 0; k < ev->Count; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + //OnClick + String methodName = ""; PMethodRec recM; + if (SameText(eInfo->EventName, "OnClick")) + { + methodName = dfm->ClassName + "." + eInfo->ProcName; + //Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà + recM = FMain_11011981->GetMethodInfo(recN, methodName); + mi->Tag = (recM) ? recM->address : 0; + mi->OnClick = miPopupClick; + //mi->Enabled = true; + continue; + } + //Action + if (SameText(eInfo->EventName, "Action")) + { + //Èùåì êîìïîíåíòó ñ èìåíåì eInfo->ProcName + for (int r = 0; r < dfm->Components->Count; r++) + { + PComponentInfo cInfo1 = (PComponentInfo)dfm->Components->Items[r]; + if (SameText(cInfo1->Name, eInfo->ProcName)) + { + //Èùåì ñîáûòèå OnExecute + TList* ev1 = cInfo1->Events; + for (int i = 0; i < ev1->Count; i++) + { + PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; + if (SameText(eInfo1->EventName, "OnExecute")) + { + methodName = dfm->ClassName + "." + eInfo1->ProcName; + recM = FMain_11011981->GetMethodInfo(recN, methodName); + mi->Tag = (recM) ? recM->address : 0; + mi->OnClick = miPopupClick; + //mi->Enabled = true; + break; + } + } + break; + } + } + } + } + menuFound = true; + return; + } + } + } + } + + if (!menuFound && formInherited && curDfm && curDfm->ParentDfm) + { + searchName = curDfm->ParentDfm->Name; + //recursive call in the parent form, trying to find the menu handler... + SetupMenuItem(mi, searchName); + } +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::DoFindMethod(String& methodName) +{ + if (FOnFindMethod) FOnFindMethod(this, getFormName(), methodName); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::CMDialogKey(TCMDialogKey& Message) +{ + //allows for example Ctrl+Tab in TabSheet + if (Message.CharCode != VK_ESCAPE) TForm::Dispatch(&Message); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::MyFormShow(TObject *Sender) +{ + if (!frmTree) + { + frmTree = new TIdrDfmFormTree_11011981(this); + int ScrWid = Screen->WorkAreaWidth; + int ScrHei = Screen->WorkAreaHeight; + int FrmWid = this->Width; + int FrmHei = this->Height; + int TrvWid = frmTree->Width; + int TrvHei = frmTree->Height; + int FrmLeft = (ScrWid - FrmWid) / 2; + + if (TrvWid < FrmLeft) + frmTree->Left = FrmLeft - TrvWid; + else + frmTree->Left = 0; + + frmTree->Top = (ScrHei - TrvHei) / 2; + frmTree->Show(); + } +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::MyFormClose(TObject *Sender, TCloseAction &Action) +{ + for (int n = 0; n < ResInfo->FormList->Count; n++) + { + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + if (dfm->Open == 2) dfm->Open = 1; + } + + //notify main window that form is closed (ugly ref to main form - refactor!) + ::SendMessage(FMain_11011981->Handle, WM_DFMCLOSED, 0, 0);//Post + + Action = caFree; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::MyFormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) +{ + switch (Key) + { + case VK_ESCAPE: + Close(); + break; + case VK_F11: + if (frmTree) frmTree->Show(); + break; + } + + Key = 0; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::MyShortCutEvent(Messages::TWMKey &Msg, bool &Handled) +{ + if (VK_ESCAPE == Msg.CharCode) + { + Close(); + Handled = true; + } +} +//--------------------------------------------------------------------------- +String __fastcall IdrDfmForm::getFormName() +{ + return String("T") + originalClassName; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmForm::SetMyHandlers() +{ + OnShow = MyFormShow; + OnClose = MyFormClose; + OnKeyDown = MyFormKeyDown; + OnShortCut = MyShortCutEvent; +} +//--------------------------------------------------------------------------- +//IdrDfmLoader +//--------------------------------------------------------------------------- +__fastcall IdrDfmLoader::IdrDfmLoader(TComponent* Owner) : TComponent(Owner) +{ + dfmForm = 0; + Counter = 0; + Current = 0; + CompsEventsList = new TCollection(__classid(TComponentEvents)); +} +//--------------------------------------------------------------------------- +__fastcall IdrDfmLoader::~IdrDfmLoader() +{ + if (CompsEventsList) delete CompsEventsList; + CompsEventsList = 0; +} +//--------------------------------------------------------------------------- +TForm* __fastcall IdrDfmLoader::LoadForm(TStream* dfmStream, TDfm* dfm, bool loadingParent) +{ + dfmForm = 0; + dfmStream->Seek(0, soFromBeginning); + + if (dfm && dfm->ParentDfm) + { + dfm->Loader = new IdrDfmLoader(0); + dfmForm = (IdrDfmForm*)dfm->Loader->LoadForm(dfm->ParentDfm->MemStream, dfm->ParentDfm, true); + delete dfm->Loader; + dfm->Loader = 0; + } + else + { + dfmForm = new IdrDfmForm(Application, 1); + } + + dfmStream->Seek(0, soFromBeginning); + TReader* Reader = new IdrDfmReader(dfmStream, 4096); + + Reader->OnAncestorNotFound = AncestorNotFound; + Reader->OnFindComponentClass = FindComponentClass; + Reader->OnCreateComponent = CreateComponent; + Reader->OnFindMethod = FindMethod; + Reader->OnError = ReaderError; + Reader->OnSetName = SetComponentName; + Reader->OnReferenceName = DoReferenceName; + + Current = (TComponentEvents*)(CompsEventsList->Add()); + Current->Component = dfmForm; + + TFilerFlags Flags; + int ChildPos; + + try + { + Reader->ReadSignature(); + Reader->ReadPrefix(Flags, ChildPos); + dfmForm->originalClassType = Reader->ReadStr(); + dfmForm->originalClassName = Reader->ReadStr(); + Reader->Position = 0; + + Reader->ReadRootComponent(dfmForm); + + dfmForm->Enabled = true; + dfmForm->Visible = false; + dfmForm->Position = poScreenCenter; + dfmForm->compsEventsList = CompsEventsList; + dfmForm->OnFindMethod = OnFindMethod; + dfmForm->SetMyHandlers(); + + dfmForm->SetDesigning(false, false); + if (!loadingParent) dfmForm->SetupControls(); + + if (dfmForm->AlphaBlend) dfmForm->AlphaBlendValue = 222; + + dfmForm->AutoSize = false; + dfmForm->WindowState = wsNormal; + dfmForm->FormStyle = fsStayOnTop; + dfmForm->FormState.Clear(); + + dfmForm->Constraints->MinWidth = 0; + dfmForm->Constraints->MinHeight = 0; + dfmForm->Constraints->MaxWidth = 0; + dfmForm->Constraints->MaxHeight = 0; + + dfmForm->HelpFile = ""; + CompsEventsList = 0; + } + catch(Exception &e) + { + ShowMessage("DFM Load Error\r\n" + e.ClassName() +": " + e.Message); + dfmForm = 0; + } + + delete Reader; + return dfmForm; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::AncestorNotFound(TReader* Reader, String ComponentName, TMetaClass* ComponentClass, TComponent* &Component) +{ + String s = ComponentClass->ClassName(); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::FindComponentClass(TReader* Reader, String ClassName, TMetaClass* &ComponentClass) +{ + try + { + ComponentClass = FindClass(ClassName); + } + catch (Exception& e) + { + lastClassAliasName = ClassName; + + String alias = ResInfo->GetAlias(ClassName); + for (int n = 0;;n++) + { + if (!RegClasses[n].RegClass) break; + if (SameText(alias, RegClasses[n].ClassName)) + { + ComponentClass = RegClasses[n].RegClass; + break; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::CreateComponent(TReader* Reader, TMetaClass* ComponentClass, TComponent* &Component) +{ + Current = 0; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::FindMethod(TReader* Reader, String MethodName, void* &Address, bool &Error) +{ + if (Current) + { + IdrDfmReader* r = dynamic_cast(Reader); + if (r) Current->FoundEvents->Add(r->PropName + "=" + MethodName); + } + + Error = false; + Address = 0; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::ReaderError(TReader* Reader, String Message, bool &Handled) +{ + //if something really wrong happened, in order to fix the + //"DFM Stream read error" - skip fault value! + if (AnsiEndsStr("Invalid property value", Message) + || AnsiEndsStr("Unable to insert a line", Message) + || AnsiContainsText(Message, "List index out of bounds") + ) + { + //move back to a type position byte + Reader->Position -= 1; + //skip the unknown value for known property (eg: Top = 11.453, or bad Items for StringList) + Reader->SkipValue(); + } + + Handled = true; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::SetComponentName(TReader* Reader, TComponent* Component, String &Name) +{ + if (Name == "") + { + Name = "_" + Val2Str4(Counter) + "_"; + Counter++; + } + + if (Current && Current->Component == Component) return; + + IdrDfmDefaultControl* rc = dynamic_cast(Component); + if (rc) + { + String mappedClassName; + try + { + mappedClassName = + //IdrDfmClassNameAnalyzer::GetInstance().GetMapping(lastClassAliasName); + ResInfo->GetAlias(lastClassAliasName); + } + catch(...) + { + } + + rc->SetClassName(lastClassAliasName, mappedClassName); + } + + Current = (TComponentEvents*)(CompsEventsList->Add()); + Current->Component = Component; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmLoader::DoReferenceName(TReader* Reader, String &Name) +{ + if(dfmForm) + { + TComponent* Component = dfmForm->FindComponent(Name); + if(Component) + { + IdrDfmDefaultControl* rc = dynamic_cast(Component); + if (rc) + { + Name = ""; + } + } + } +} +//--------------------------------------------------------------------------- +bool __fastcall IdrDfmLoader::HasGlyph(String ClassName) +{ + for (int n = 0; n < ResInfo->FormList->Count; n++) + { + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + for (int m = 0; m < dfm->Components->Count; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + if (SameText(cInfo->ClassName, ClassName)) return cInfo->HasGlyph; + } + } + return false; +} +//--------------------------------------------------------------------------- +//IdrDfmDefaultControl +//--------------------------------------------------------------------------- +__fastcall IdrDfmDefaultControl::IdrDfmDefaultControl(TObject* Owner) : TPanel(Owner) +{ + Color = clNone; + imgIcon = 0; +} +//--------------------------------------------------------------------------- +bool IdrDfmDefaultControl::IsVisible() +{ + return (Width > 0 && Height > 0); +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmDefaultControl::ReadState(TReader* Reader) +{ + DisableAlign(); + + try{ + Width = 24; + Height = 24; + TPanel::ReadState(Reader); + } + __finally + //catch(Exception& e) + { + EnableAlign(); + } + + /* wow, intersting case seen, D7: + + object WebDispatcher1: TWebDispatcher + OldCreateOrder = False + Actions = <> + Left = 888 + Top = 8 + Height = 0 + Width = 0 + end + + we are not happy with 0:0 sizes, lets correct + */ + + if (Width <= 0) + Width = 24; + if (Height <= 0) + Height = 24; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmDefaultControl::Loaded() +{ + TPanel::Loaded(); + + BorderStyle = bsNone; + if (Color == clNone) Color = clBtnFace; +} +//--------------------------------------------------------------------------- +void __fastcall IdrDfmDefaultControl::Paint() +{ + Canvas->Brush->Color = Color; + Canvas->Brush->Style = bsClear; + Canvas->Pen->Color = clGray; + Canvas->Pen->Style = psDot; + Canvas->Rectangle(GetClientRect()); +} +//--------------------------------------------------------------------------- +void IdrDfmDefaultControl::SetClassName(const String& name, const String& mappedName) +{ + originalClassName = name; + //as note: + //here we should have mapped class, eg: + //we have on form TMyOpenDialog component, it was mapped to TOpenDialog, + //so I expect to have a string "TOpenDialog in mappedName, not "Default" ! + + mappedClassName = name; + + String usedClassName = (mappedClassName.IsEmpty()) ? originalClassName : mappedClassName; + + if (HasIconForClass(usedClassName)) + { + CreateImageIconForClass(usedClassName); + } +} +//--------------------------------------------------------------------------- +bool IdrDfmDefaultControl::HasIconForClass(const String& name) +{ + return true; + //TBD: ask dll if it has specified icon for class + //right now it is implicitly done in CreateImageIconForClass() +} +//--------------------------------------------------------------------------- +void IdrDfmDefaultControl::CreateImageIconForClass(const String& imgFile) +{ + static HINSTANCE hResLib = 0; + static bool IconsDllLoaded = false; + static bool IconsDllPresent = true; + if (!IconsDllPresent) + return; + + if (!IconsDllLoaded) + { + hResLib = LoadLibrary("Icons.dll"); + IconsDllLoaded = IconsDllPresent = (hResLib != 0); + if (!IconsDllPresent) + return; + } + + imgIcon = new TImage(this); + //old way - read from .bmp files on disk + //imgIcon->Picture->LoadFromFile(imgFile); + try{ + imgIcon->Picture->Bitmap->LoadFromResourceName((int)hResLib, imgFile.UpperCase()); + imgIcon->AutoSize = true; + imgIcon->Transparent = true; + imgIcon->Parent = this; + + //yes, we want same popup as our parent + //imgIcon->OnMouseDown = ImageMouseDown; + + //update our component size in a case picture has another size + if (Width != imgIcon->Picture->Bitmap->Width) + Width = imgIcon->Picture->Bitmap->Width; + if (Height != imgIcon->Picture->Bitmap->Height) + Height = imgIcon->Picture->Bitmap->Height; + + }catch(Exception& e){ + //icon not found or other error - free the image! + imgIcon->Parent = 0; + delete imgIcon; + imgIcon = 0; + } +} + +//--------------------------------------------------------------------------- +void __fastcall IdrDfmDefaultControl::ImageMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if (Button == mbRight) + { + //Sender here is image, but we need this - replacing control! + if (Parent) + ((TMyControl*)Parent)->OnMouseDown(this, Button, Shift, X, Y); + } +} +//--------------------------------------------------------------------------- +//IdrImageControl +//--------------------------------------------------------------------------- +__fastcall IdrImageControl::IdrImageControl(TComponent* Owner) : TImage(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall IdrImageControl::Paint() +{ +} +//--------------------------------------------------------------------------- + diff --git a/Resources.h b/Resources.h new file mode 100644 index 0000000..eedd411 --- /dev/null +++ b/Resources.h @@ -0,0 +1,225 @@ +//--------------------------------------------------------------------------- +#ifndef ResourcesH +#define ResourcesH +//--------------------------------------------------------------------------- +#include +#include + +#include "UfrmFormTree.h" +//--------------------------------------------------------------------------- +typedef struct +{ + String CompName; //Component Name + String EventName; //Event Name + int Adr; //Event Address +} EventListItem, *PEventListItem; + +typedef struct +{ + TMetaClass *RegClass; + char *ClassName; +} RegClassInfo, *PRegClassInfo; + +typedef struct +{ + String EventName; //Event name (OnClose) + String ProcName; //Event handler name (CloseBtnClick) +} EventInfo, *PEventInfo; + +typedef struct +{ + bool Inherit; //Component is inherited + bool HasGlyph; //Component has property "Glyph" + String Name; //Component name + String ClassName; //Component class + TList *Events; //EventInfo list +} ComponentInfo, *PComponentInfo; + +class IdrDfmLoader; + +#define FF_INHERITED 1 +#define FF_HASNOTEBOOK 2 + +//Records to resource list +class TDfm +{ +public: + __fastcall TDfm(); + __fastcall ~TDfm(); + BYTE Open; //2 - form opened; 1 - form closed but loader not destroyed; 0 - form closed + BYTE Flags; //Form flags (see FF_...) + String ResName; //Resource name (ABOUTDIALOG) + String Name; //Form name (AboutDialog) + String ClassName; //Form class (TAboutDialog) + TMemoryStream *MemStream; //Memory Stream, containing Resource Data + TDfm *ParentDfm; //Parent form + TList *Events; //Form events list + TList *Components; //Form components list + TForm *Form; //Pointer to opened form + IdrDfmLoader *Loader; //Form loader + bool __fastcall IsFormComponent(String CompName); +}; + +class TResourceInfo +{ +public: + __fastcall TResourceInfo(); + __fastcall ~TResourceInfo(); + void __fastcall GetFormAsText(TDfm* Dfm, TStrings* DstList); + bool __fastcall EnumResources(String FileName); + void __fastcall ShowResources(TListBox* ListBox); + void __fastcall GetBitmap(TDfm* Dfm, Graphics::TBitmap* DstBitmap); + TDfm* __fastcall GetParentDfm(TDfm* Dfm); + void __fastcall CloseAllForms(); + void __fastcall ReopenAllForms(); + void __fastcall InitAliases(); + String __fastcall GetAlias(String ClassName); + TDfm* __fastcall GetFormIdx(String FormName, int* idx); + TDfm* __fastcall GetFormByClassName(String ClassName); + void __fastcall GetEventsList(String FormName, TList* Lst); + bool citadel; + int Counter; + HINSTANCE hFormPlugin; + String FormPluginName; + TList *FormList; //Form names list + TStringList *Aliases; //Aliases list +}; + +class TMyControl : public TControl +{ +public: + __property OnClick; + __property OnMouseDown; + __property PopupMenu; +}; + +class IdrDfmReader: public TReader +{ +public: + __fastcall IdrDfmReader(TStream* Stream, int BufSize); + __property PropName; +}; + +class TComponentEvents : public TCollectionItem +{ +public: + __fastcall TComponentEvents(TCollection* Owner); + virtual __fastcall ~TComponentEvents(); + + TComponent *Component; + TStringList *FoundEvents; +} ; + +typedef void __fastcall (__closure *TFindMethodSourceEvent) + (TObject* Sender, String& ClassName, String& MethodName); + +class IdrDfmForm : public TForm +{ +public: + __fastcall IdrDfmForm(TComponent* Owner); + __fastcall IdrDfmForm(TComponent* Owner, int Dummy); + virtual __fastcall ~IdrDfmForm(); + + String originalClassName; + String originalClassType; + TComponentEvents *current; + TCollection *compsEventsList; + TPopupMenu* evPopup; + TIdrDfmFormTree_11011981* frmTree; + + void __fastcall SetupControls(); + void __fastcall SetupControlResetShortcut(TComponent* component); + void __fastcall SetDesigning(bool value, bool SetChildren); + void __fastcall SetMyHandlers(); + __property TFindMethodSourceEvent OnFindMethod = {read = FOnFindMethod, write = FOnFindMethod, default = 0}; +protected: + virtual void __fastcall CreateHandle(); + void __fastcall SetupControlHint(String FormName, TControl* Control, String InitHint); + void __fastcall SetupMenuItem(TMenuItem* mi, String searchName); + void __fastcall ActionExecute(TObject* Sender); + void __fastcall miClick(TObject* Sender); + void __fastcall ControlMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y); + void __fastcall miPopupClick(TObject *Sender); + + BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(CM_DIALOGKEY, TCMDialogKey, CMDialogKey) + END_MESSAGE_MAP(TForm) +private: + TFindMethodSourceEvent FOnFindMethod; + String __fastcall getFormName(); + void __fastcall DoFindMethod(String& methodName); + void __fastcall CMDialogKey(TCMDialogKey& Message); + void __fastcall MyFormShow(TObject *Sender); + void __fastcall MyFormClose(TObject *Sender, TCloseAction &Action); + void __fastcall MyFormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall MyShortCutEvent(Messages::TWMKey &Msg, bool &Handled); + void __fastcall ShowMyPopupMenu(String FormName, String ControlName, bool show); +}; + +class IdrDfmLoader : public TComponent +{ +public: + __fastcall IdrDfmLoader(TComponent* Owner); + virtual __fastcall ~IdrDfmLoader(); + + TForm* __fastcall LoadForm(TStream* dfmStream, TDfm* dfm, bool loadingParent = false); + __property TFindMethodSourceEvent OnFindMethod = {read = FOnFindMethod, write = SetOnFindMethod, default = 0}; + +protected: + int Counter; + TComponentEvents *Current; + TCollection *CompsEventsList; + String lastClassAliasName; + + void __fastcall AncestorNotFound(TReader* Reader, String ComponentName, TMetaClass* ComponentClass, TComponent* &Component); + void __fastcall ReaderError(TReader* Reader, String Message, bool &Handled); + void __fastcall FindComponentClass(TReader* Reader, String ClassName, TMetaClass* &ComponentClass); + void __fastcall CreateComponent(TReader* Reader, TMetaClass* ComponentClass, TComponent* &Component); + void __fastcall FindMethod(TReader* Reader, String MethodName, void* &Address, bool &Error); + void __fastcall SetComponentName(TReader* Reader, TComponent* Component, String &Name); + + void __fastcall DoReferenceName(TReader* Reader, String &Name); + void __fastcall SetOnFindMethod(TFindMethodSourceEvent method); + bool __fastcall HasGlyph(String ClassName); +private: + IdrDfmForm* dfmForm; + TFindMethodSourceEvent FOnFindMethod; + TComponent *FindComp(TComponent* Owner, String& compnay); +}; + +class IdrDfmDefaultControl : public TPanel +{ +public: + __fastcall IdrDfmDefaultControl(TObject* Owner); + + bool IsVisible(); + void SetClassName(const String& name, const String& mappedName); + String GetOrigClassName(){return originalClassName;} + +protected: + virtual void __fastcall Loaded(); + virtual void __fastcall ReadState(TReader* Reader); + virtual void __fastcall Paint(); + +private: + String originalClassName, mappedClassName; + + bool HasIconForClass(const String& name); + void CreateImageIconForClass(const String& imgFile); + + //image for std nonvisual controls (dialogs, etc) (dclstd60.bpl has images) + TImage* imgIcon; + void __fastcall ImageMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y); + +}; + +class IdrImageControl : public TImage +{ +public: + __fastcall IdrImageControl(TComponent* Owner); +protected: + virtual void __fastcall Paint(); +}; +//--------------------------------------------------------------------------- +#endif + diff --git a/Sources/Forms/AboutDlg.cpp b/Sources/Forms/AboutDlg.cpp deleted file mode 100644 index 69894f9..0000000 --- a/Sources/Forms/AboutDlg.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// --------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "AboutDlg.h" -#include "Misc.h" -extern String IDRVersion; -// --------------------------------------------------------------------- -#pragma resource "*.dfm" -TFAboutDlg_11011981 *FAboutDlg_11011981; - -// --------------------------------------------------------------------- -__fastcall TFAboutDlg_11011981::TFAboutDlg_11011981(TComponent* AOwner) : TForm(AOwner) { -} - -// --------------------------------------------------------------------- -void __fastcall TFAboutDlg_11011981::FormCreate(TObject *Sender) { - lVer->Caption = "Version: " + IDRVersion; -} - -// --------------------------------------------------------------------------- -void __fastcall TFAboutDlg_11011981::lEmailClick(TObject *Sender) { - ShellExecute(Handle, _T("open"), _T("mailto:crypto2011@gmail.com"), 0, 0, 1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFAboutDlg_11011981::lWWWClick(TObject *Sender) { - ShellExecute(Handle, _T("open"), _T("http://kpnc.org/idr32/en/"), 0, 0, 1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFAboutDlg_11011981::bDonateClick(TObject *Sender) { - ShellExecute(Handle, _T("open"), _T("http://kpnc.org/idr32/en/donation.htm"), 0, 0, 1); -} -// --------------------------------------------------------------------------- - diff --git a/Sources/Forms/AboutDlg.h b/Sources/Forms/AboutDlg.h deleted file mode 100644 index 52051c6..0000000 --- a/Sources/Forms/AboutDlg.h +++ /dev/null @@ -1,54 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef AboutDlgH -#define AboutDlgH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -#include -#include - -// ----------------------------------------------------------------------------// ---------------------------------------------------------------------------- -class TFAboutDlg_11011981 : public TForm { -__published: - TPanel *Panel3; - TButton *Button2; - TPageControl *PageControl1; - TTabSheet *tsIDR; - TTabSheet *tsCrypto; - TImage *Icon; - TLabel *lProduct; - TShape *Shape1; - TShape *Shape2; - TLabel *lVer; - TLabel *lEmail; - TLabel *lWWW; - TLabel *Label1; - TLabel *Label2; - TLabel *Label3; - TLabel *Label4; - TLabel *Label5; - TLabel *Label6; - TImage *Image1; - TBitBtn *bDonate; - TLabel *Label7; - TLabel *Label8; - TLabel *lblHint; - - void __fastcall FormCreate(TObject *Sender); - void __fastcall lEmailClick(TObject *Sender); - void __fastcall lWWWClick(TObject *Sender); - void __fastcall bDonateClick(TObject *Sender); - -private: -public: - virtual __fastcall TFAboutDlg_11011981(TComponent* AOwner); -}; - -// ---------------------------------------------------------------------------- -extern PACKAGE TFAboutDlg_11011981 *FAboutDlg_11011981; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/ActiveProcesses.cpp b/Sources/Forms/ActiveProcesses.cpp deleted file mode 100644 index 99e03ef..0000000 --- a/Sources/Forms/ActiveProcesses.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// --------------------------------------------------------------------------- - -#include -#pragma hdrstop - -// #include -#include "Main.h" -#include "ActiveProcesses.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" - -TFActiveProcesses *FActiveProcesses; - -// --------------------------------------------------------------------- -__fastcall TFActiveProcesses::TFActiveProcesses(TComponent* AOwner) : TForm(AOwner) { -} - -// --------------------------------------------------------------------------- -void TFActiveProcesses::GenerateProcessList() { - ListViewProcesses->Items->BeginUpdate(); - ListViewProcesses->Clear(); - - TProcessManager PM; - - if (!PM.GenerateProcessList()) { - ShowMessage("Error getting the list of processes"); - return; - } - - for (std::vector::iterator it = PM.ProcessList.begin(); it != PM.ProcessList.end(); ++it) { - TListItem *ListItem = ListViewProcesses->Items->Add(); - ListItem->Caption = IntToHex((int)it->Pid, 4); - ListItem->SubItems->Add(it->Name); - ListItem->SubItems->Add(IntToHex((int)it->ImageSize, 8)); - ListItem->SubItems->Add(IntToHex((int)it->EntryPoint, 8)); - ListItem->SubItems->Add(IntToHex((int)it->BaseAddress, 8)); - } - - ListViewProcesses->Items->EndUpdate(); - ListViewProcesses->Repaint(); - ListViewProcesses->Refresh(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFActiveProcesses::FormShow(TObject *Sender) { - GenerateProcessList(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFActiveProcesses::PMProcessDumpClick(TObject *Sender) { - DWORD _pid, _boc, _poc, _imb; - TListItem *_li; - TMemoryStream *_stream; - TMemoryStream *_stream1; - String _item; - TProcessManager PM; - - try { - _li = ListViewProcesses->Selected; - _pid = StrToInt("0x" + _li->Caption); - _stream = new TMemoryStream; - PM.DumpProcess(_pid, _stream, &_boc, &_poc, &_imb); - if (!_stream->Size) { - delete _stream; - return; - } - _stream->SaveToFile("__idrtmp__.exe"); - delete _stream; - FMain_11011981->DoOpenDelphiFile(DELHPI_VERSION_AUTO, "__idrtmp__.exe", false, false); - } - catch (const Exception &ex) { - ShowMessage("Dumper failed: " + ex.Message); - } - - Close(); -} -// --------------------------------------------------------------------------- - -void __fastcall TFActiveProcesses::PMProcessPopup(TObject *Sender) { - PMProcessDump->Enabled = (ListViewProcesses->Selected); -} -// --------------------------------------------------------------------------- - -void __fastcall TFActiveProcesses::PMProcessRefreshClick(TObject *Sender) { - GenerateProcessList(); -} -// --------------------------------------------------------------------------- - \ No newline at end of file diff --git a/Sources/Forms/ActiveProcesses.h b/Sources/Forms/ActiveProcesses.h deleted file mode 100644 index 5dce212..0000000 --- a/Sources/Forms/ActiveProcesses.h +++ /dev/null @@ -1,39 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef ActiveProcessesH -#define ActiveProcessesH -// --------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -#include "ProcessManager.h" - -// --------------------------------------------------------------------------- -class TFActiveProcesses : public TForm { -__published: - TListView *ListViewProcesses; - TPopupMenu *PMProcess; - TMenuItem *PMProcessDump; - TMenuItem *N1; - TMenuItem *PMProcessRefresh; - void __fastcall FormShow(TObject *Sender); - void __fastcall PMProcessDumpClick(TObject *Sender); - void __fastcall PMProcessPopup(TObject *Sender); - void __fastcall PMProcessRefreshClick(TObject *Sender); - -private: - void GenerateProcessList(); - -public: - - virtual __fastcall TFActiveProcesses(TComponent* AOwner); -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFActiveProcesses *FActiveProcesses; -// --------------------------------------------------------------------------- -#endif - \ No newline at end of file diff --git a/Sources/Forms/EditFieldsDlg.cpp b/Sources/Forms/EditFieldsDlg.cpp deleted file mode 100644 index ce255d5..0000000 --- a/Sources/Forms/EditFieldsDlg.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// ---------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Misc.h" -#include "EditFieldsDlg.h" -#include "Main.h" -// ---------------------------------------------------------------------------- -#pragma resource "*.dfm" - -extern bool ProjectModified; -extern DWORD CurProcAdr; -extern DWORD CodeBase; -extern DWORD *Flags; -extern PInfoRec *Infos; - -TFEditFieldsDlg_11011981 *FEditFieldsDlg_11011981; - -// ---------------------------------------------------------------------------- -__fastcall TFEditFieldsDlg_11011981::TFEditFieldsDlg_11011981(TComponent *Owner) : TForm(Owner) { - Op = FD_OP_EDIT; - SelIndex = -1; - FieldOffset = -1; - VmtAdr = 0; - fieldsList = new TList; -} - -// ---------------------------------------------------------------------------- -__fastcall TFEditFieldsDlg_11011981::~TFEditFieldsDlg_11011981() { - if (fieldsList) - delete fieldsList; -} - -// ---------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::ShowFields() { - lbFields->Enabled = true; - lbFields->Clear(); - fieldsList->Clear(); - int fieldsNum = FMain_11011981->LoadFieldTable(VmtAdr, fieldsList); - if (fieldsNum) { - SelIndex = -1; - for (int n = 0; n < fieldsNum; n++) { - PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[n]; - String line = Val2Str5(fInfo->Offset) + " "; - if (fInfo->Name != "") - line += fInfo->Name; - else - line += "?"; - line += ":"; - if (fInfo->Type != "") - line += fInfo->Type; - else - line += "?"; - lbFields->Items->Add(line); - if (fInfo->Offset == FieldOffset) - SelIndex = n; - } - } -} - -// ---------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::FormShow(TObject *Sender) { - Caption = GetClsName(VmtAdr) + " fields"; - - edtPanel->Visible = false; - lbFields->Height = lbFXrefs->Height; - - lbFXrefs->Clear(); - ShowFields(); - lbFields->ItemIndex = SelIndex; - - bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); - bAdd->Enabled = true; - bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); - bClose->Enabled = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::lbFXrefsDblClick(TObject *Sender) { - char type[2]; - DWORD adr; - - String item = lbFXrefs->Items->Strings[lbFXrefs->ItemIndex]; - sscanf(AnsiString(item).c_str() + 1, "%lX%2c", &adr, type); - - for (int m = Adr2Pos(adr); m >= 0; m--) { - if (IsFlagSet(cfProcStart, m)) { - FMain_11011981->ShowCode(Pos2Adr(m), adr, -1, -1); - break; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::lbFieldsClick(TObject *Sender) { - lbFXrefs->Clear(); - - if (lbFields->ItemIndex == -1) - return; - - String line; - PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; - if (fInfo->xrefs) { - for (int n = 0; n < fInfo->xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)fInfo->xrefs->Items[n]; - line = Val2Str8(recX->adr + recX->offset); - if (recX->type == 'c') - line += " <-"; - lbFXrefs->Items->Add(line); - } - } - bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); - bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::bEditClick(TObject *Sender) { - Op = FD_OP_EDIT; - lbFields->Height = lbFXrefs->Height - edtPanel->Height; - edtPanel->Visible = true; - - PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; - edtOffset->Text = Val2Str0(fInfo->Offset); - edtOffset->Enabled = false; - edtName->Text = fInfo->Name; - edtName->Enabled = true; - edtType->Text = fInfo->Type; - edtType->Enabled = true; - edtName->SetFocus(); - - lbFields->Enabled = false; - bApply->Enabled = false; - bClose->Enabled = true; - bEdit->Enabled = false; - bAdd->Enabled = false; - bRemove->Enabled = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::edtNameChange(TObject *Sender) { - bApply->Enabled = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::edtTypeChange(TObject *Sender) { - bApply->Enabled = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::bApplyClick(TObject *Sender) { - bool vmt, ok = false; - DWORD adr; - int n, size, offset, fromOfs, toOfs; - PInfoRec recN; - PFIELDINFO fInfo; - String rtti; - - recN = GetInfoRec(VmtAdr); - switch (Op) { - case FD_OP_EDIT: - fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; - fInfo->Name = edtName->Text; - fInfo->Type = edtType->Text; - // Delete all fields (if exists) that covered by new type - fromOfs = fInfo->Offset; - if (GetTypeKind(edtType->Text, &size) == ikRecord) { - - toOfs = fromOfs + size; - for (n = 0; n < fieldsList->Count; n++) { - fInfo = (PFIELDINFO)fieldsList->Items[n]; - offset = fInfo->Offset; - if (offset > fromOfs && offset < toOfs) { - recN->vmtInfo->RemoveField(offset); - } - } - } - break; - case FD_OP_ADD: - case FD_OP_DELETE: - sscanf(AnsiString(edtOffset->Text.Trim()).c_str(), "%lX", &offset); - if (Op == FD_OP_ADD) { - fInfo = FMain_11011981->GetField(recN->GetName(), offset, &vmt, &adr, ""); - if (!fInfo || Application->MessageBox(L"Field already exists", L"Replace?", MB_YESNO) == IDYES) - recN->vmtInfo->AddField(0, 0, FIELD_PUBLIC, offset, -1, edtName->Text, edtType->Text); - if (fInfo && fInfo->Scope == SCOPE_TMP) - delete fInfo; - } - if (Op == FD_OP_DELETE) { - if (Application->MessageBox(L"Delete field?", L"Confirmation", MB_YESNO) == IDYES) - recN->vmtInfo->RemoveField(offset); - } - break; - } - int itemidx = lbFields->ItemIndex; - int topidx = lbFields->TopIndex; - ShowFields(); - lbFields->ItemIndex = itemidx; - lbFields->TopIndex = topidx; - - FMain_11011981->RedrawCode(); - FMain_11011981->ShowClassViewer(VmtAdr); - - edtPanel->Visible = false; - lbFields->Height = lbFXrefs->Height; - - lbFields->Enabled = true; - bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); - bAdd->Enabled = true; - bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); - - ProjectModified = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::bCloseClick(TObject *Sender) { - edtPanel->Visible = false; - lbFields->Height = lbFXrefs->Height; - - lbFields->Enabled = true; - bEdit->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); - bAdd->Enabled = true; - bRemove->Enabled = (lbFields->Count && lbFields->ItemIndex != -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::bAddClick(TObject *Sender) { - Op = FD_OP_ADD; - lbFields->Height = lbFXrefs->Height - edtPanel->Height; - edtPanel->Visible = true; - - edtOffset->Text = ""; - edtOffset->Enabled = true; - edtName->Text = ""; - edtName->Enabled = true; - edtType->Text = ""; - edtType->Enabled = true; - edtOffset->SetFocus(); - - lbFields->Enabled = false; - bApply->Enabled = false; - bClose->Enabled = true; - bEdit->Enabled = false; - bAdd->Enabled = false; - bRemove->Enabled = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::bRemoveClick(TObject *Sender) { - Op = FD_OP_DELETE; - lbFields->Height = lbFXrefs->Height - edtPanel->Height; - edtPanel->Visible = true; - - PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[lbFields->ItemIndex]; - edtOffset->Text = Val2Str0(fInfo->Offset); - edtOffset->Enabled = false; - edtName->Text = fInfo->Name; - edtName->Enabled = false; - edtType->Text = fInfo->Type; - edtType->Enabled = false; - - lbFields->Enabled = false; - bApply->Enabled = true; - bClose->Enabled = true; - bEdit->Enabled = false; - bAdd->Enabled = false; - bRemove->Enabled = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFieldsDlg_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/EditFieldsDlg.h b/Sources/Forms/EditFieldsDlg.h deleted file mode 100644 index 85accb4..0000000 --- a/Sources/Forms/EditFieldsDlg.h +++ /dev/null @@ -1,58 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef EditFieldsDlgH -#define EditFieldsDlgH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include -// ---------------------------------------------------------------------------- -#define FD_OP_EDIT 0 -#define FD_OP_ADD 1 -#define FD_OP_DELETE 2 - -class TFEditFieldsDlg_11011981 : public TForm { -__published: - TListBox *lbFXrefs; - TListBox *lbFields; - TPanel *Panel1; - TButton *bAdd; - TButton *bRemove; - TPanel *edtPanel; - TLabeledEdit *edtName; - TLabeledEdit *edtType; - TButton *bApply; - TButton *bClose; - TLabeledEdit *edtOffset; - TButton *bEdit; - - void __fastcall FormShow(TObject *Sender); - void __fastcall lbFXrefsDblClick(TObject *Sender); - void __fastcall lbFieldsClick(TObject *Sender); - void __fastcall edtNameChange(TObject *Sender); - void __fastcall edtTypeChange(TObject *Sender); - void __fastcall bCloseClick(TObject *Sender); - void __fastcall bApplyClick(TObject *Sender); - void __fastcall bEditClick(TObject *Sender); - void __fastcall bRemoveClick(TObject *Sender); - void __fastcall bAddClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: - void __fastcall ShowFields(); - -public: - BYTE Op; - int SelIndex; - int FieldOffset; - DWORD VmtAdr; - TList *fieldsList; - - virtual __fastcall TFEditFieldsDlg_11011981(TComponent *Owner); - virtual __fastcall ~TFEditFieldsDlg_11011981(); -}; - -// ---------------------------------------------------------------------------- -extern TFEditFieldsDlg_11011981 *FEditFieldsDlg_11011981; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/EditFunctionDlg.cpp b/Sources/Forms/EditFunctionDlg.cpp deleted file mode 100644 index de231b9..0000000 --- a/Sources/Forms/EditFunctionDlg.cpp +++ /dev/null @@ -1,764 +0,0 @@ -// --------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Misc.h" -#include "EditFunctionDlg.h" -// --------------------------------------------------------------------- -#pragma resource "*.dfm" - -extern bool ProjectModified; -extern DWORD CodeBase; -extern PInfoRec *Infos; -extern DWORD *Flags; -extern TList *VmtList; -extern char StringBuf[MAXSTRBUFFER]; -extern MKnowledgeBase KnowledgeBase; - -TFEditFunctionDlg_11011981 *FEditFunctionDlg_11011981; - -// --------------------------------------------------------------------- -__fastcall TFEditFunctionDlg_11011981::TFEditFunctionDlg_11011981(TComponent* AOwner) : TForm(AOwner) { - VmtCandidatesNum = 0; -} - -// --------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bOkClick(TObject *Sender) { - ModalResult = mrOk; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_ESCAPE) - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FormShow(TObject *Sender) { - PInfoRec recN = GetInfoRec(Adr); - SFlags = recN->procInfo->flags; - SName = recN->GetName(); - EndAdr = Adr + recN->procInfo->procSize - 1; - lEndAdr->Text = Val2Str0(EndAdr); - StackSize = recN->procInfo->stackSize; - lStackSize->Text = Val2Str0(StackSize); - - FillVMTCandidates(); - pc->ActivePage = tsType; - // Type - cbMethod->Enabled = false; - cbVmtCandidates->Enabled = false; - mType->Enabled = false; - - cbEmbedded->Enabled = false; - lEndAdr->Enabled = false; - lStackSize->Enabled = false; - rgFunctionKind->Enabled = false; - rgCallKind->Enabled = false; - bApplyType->Enabled = false; - bCancelType->Enabled = false; - FillType(); - // Args - lbArgs->Enabled = true; - FillArgs(); - // Vars - lbVars->Enabled = true; - pnlVars->Visible = false; - edtVarOfs->Text = ""; - edtVarSize->Text = ""; - edtVarName->Text = ""; - edtVarType->Text = ""; - FillVars(); - // Buttons - bEdit->Enabled = true; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - bOk->Enabled = false; - - TypModified = false; - VarModified = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bEditClick(TObject *Sender) { - if (pc->ActivePage == tsType) { - cbMethod->Enabled = true; - cbVmtCandidates->Enabled = true; - mType->Enabled = true; - cbEmbedded->Enabled = true; - lEndAdr->Enabled = true; - lStackSize->Enabled = true; - rgFunctionKind->Enabled = true; - rgCallKind->Enabled = true; - bApplyType->Enabled = true; - bCancelType->Enabled = true; - } - else if (pc->ActivePage == tsVars) { - edtVarOfs->Text = ""; - edtVarName->Text = ""; - edtVarType->Text = ""; - - PInfoRec recN = GetInfoRec(Adr); - PLOCALINFO locInfo = PLOCALINFO(recN->procInfo->locals->Items[lbVars->ItemIndex]); - if (locInfo) { - edtVarOfs->Text = IntToHex((int)locInfo->Ofs, 0); - edtVarSize->Text = String(locInfo->Size); - edtVarName->Text = String(locInfo->Name); - edtVarType->Text = String(locInfo->TypeDef); - } - - lbVars->Height = pc->Height - pnlVars->Height; - pnlVars->Visible = true; - } - - lbArgs->Enabled = false; - lbVars->Enabled = false; - // Buttons - bEdit->Enabled = false; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::lbVarsClick(TObject *Sender) { - bEdit->Enabled = (lbVars->SelCount == 1); - bRemoveSelected->Enabled = (lbVars->SelCount > 0); - bRemoveAll->Enabled = (lbVars->Count > 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::pcChange(TObject *Sender) { - if (pc->ActivePage == tsType) { - bEdit->Enabled = true; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - } - else if (pc->ActivePage == tsArgs) { - bEdit->Enabled = false; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - return; - } - else { - bAdd->Enabled = false; - if (lbVars->Count > 0) { - bEdit->Enabled = (lbVars->SelCount == 1); - bRemoveSelected->Enabled = (lbVars->SelCount > 0); - bRemoveAll->Enabled = (lbVars->Count > 0); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bApplyTypeClick(TObject *Sender) { - if (cbMethod->Checked && cbVmtCandidates->Text == "") { - ShowMessage("Class name is empty"); - return; - } - - DWORD newEndAdr; - int tempInt; - if (lEndAdr->Text == "" || !TryStrToInt(String("$") + lEndAdr->Text, tempInt)) { - ShowMessage("End address is not valid"); - return; - } - newEndAdr = StrToInt(String("$") + lEndAdr->Text); - if (!IsValidCodeAdr(newEndAdr)) { - ShowMessage("End address is not valid"); - return; - } - - if (lStackSize->Text == "" || !TryStrToInt(String("$") + lStackSize->Text, StackSize)) { - ShowMessage("StackSize not valid"); - return; - } - StackSize = StrToInt(String("$") + lStackSize->Text); - - PInfoRec recN = GetInfoRec(Adr); - // Set new procSize - recN->procInfo->procSize = newEndAdr - Adr + 1; - - switch (rgFunctionKind->ItemIndex) { - case 0: - recN->kind = ikConstructor; - break; - case 1: - recN->kind = ikDestructor; - break; - case 2: - recN->kind = ikProc; - recN->type = ""; - break; - case 3: - recN->kind = ikFunc; - break; - } - - recN->procInfo->flags &= 0xFFFFFFF8; - recN->procInfo->flags |= rgCallKind->ItemIndex; - - if (cbEmbedded->Checked) - recN->procInfo->flags |= PF_EMBED; - else - recN->procInfo->flags &= ~PF_EMBED; - - String line, decl = ""; - for (int n = 0; n < mType->Lines->Count; n++) { - line = mType->Lines->Strings[n].Trim(); - if (line == "") - continue; - decl += line; - } - - decl = decl.Trim(); - char* p = AnsiString(decl).AnsiLastChar(); - if (*p == ';') - * p = ' '; - p = AnsiString(decl).c_str(); - String name = ""; - for (int len = 0; ; len++) { - char c = *p; - if (!c || c == ' ' || c == '(' || c == ';' || c == ':') { - *p = 0; - name = decl.SubString(1, len); - *p = c; - break; - } - p++; - } - - if (recN->kind == ikConstructor) { - recN->SetName(cbVmtCandidates->Text + ".Create"); - } - else if (recN->kind == ikDestructor) { - recN->SetName(cbVmtCandidates->Text + ".Destroy"); - } - else if (SameText(name, GetDefaultProcName(Adr))) { - if (cbMethod->Checked && (recN->procInfo->flags & PF_ALLMETHODS)) - recN->SetName(cbVmtCandidates->Text + "." + name); - else - recN->SetName(""); - } - else { - if (cbMethod->Checked && (recN->procInfo->flags & PF_ALLMETHODS)) - recN->SetName(cbVmtCandidates->Text + "." + ExtractProcName(name)); - else - recN->SetName(name); - } - - recN->procInfo->DeleteArgs(); - int from = 0; - if (recN->kind == ikConstructor || recN->kind == ikDestructor) { - recN->procInfo->AddArg(0x21, 0, 4, "Self", cbVmtCandidates->Text); - recN->procInfo->AddArg(0x21, 1, 4, "_Dv__", "Boolean"); - from = 2; - } - else if (recN->procInfo->flags & PF_ALLMETHODS) { - recN->procInfo->AddArg(0x21, 0, 4, "Self", cbVmtCandidates->Text); - from = 1; - } - String retType = recN->procInfo->AddArgsFromDeclaration(p, from, rgCallKind->ItemIndex); - - if (recN->kind == ikFunc) - recN->type = retType; - - recN->procInfo->stackSize = StackSize; - - FillType(); - FillArgs(); - - cbMethod->Enabled = false; - mType->Enabled = false; - cbEmbedded->Enabled = false; - lEndAdr->Enabled = false; - lStackSize->Enabled = false; - rgFunctionKind->Enabled = false; - rgCallKind->Enabled = false; - bApplyType->Enabled = false; - bCancelType->Enabled = false; - // Buttons - bEdit->Enabled = true; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - bOk->Enabled = true; - - TypModified = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bCancelTypeClick(TObject *Sender) { - if (!TypModified) { - PInfoRec recN = GetInfoRec(Adr); - recN->SetName(SName); - recN->procInfo->flags = SFlags; - } - FillType(); - cbMethod->Enabled = false; - cbVmtCandidates->Enabled = false; - mType->Enabled = false; - cbEmbedded->Enabled = false; - lEndAdr->Enabled = false; - lStackSize->Enabled = false; - rgFunctionKind->Enabled = false; - rgCallKind->Enabled = false; - bApplyType->Enabled = false; - bCancelType->Enabled = false; - // Buttons - bEdit->Enabled = true; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - bOk->Enabled = false; - TypModified = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bApplyVarClick(TObject *Sender) { - int recofs, size; - String fname, ftype, name, type; - - try { - recofs = StrToInt("$" + edtVarOfs->Text.Trim()); - } - catch (Exception &E) { - ShowMessage("Invalid offset"); - edtVarOfs->SetFocus(); - return; - } - try { - size = StrToInt("$" + edtVarSize->Text.Trim()); - } - catch (Exception &E) { - ShowMessage("Invalid size"); - edtVarSize->SetFocus(); - return; - } - - // Insert by ZGL - PInfoRec recN = GetInfoRec(Adr); - PLOCALINFO locInfo = PLOCALINFO(recN->procInfo->locals->Items[lbVars->ItemIndex]); - //////////// - - recofs = locInfo->Ofs; - fname = edtVarName->Text.Trim(); - locInfo->Name = fname; // ZGL add - ftype = edtVarType->Text.Trim(); - locInfo->TypeDef = ftype; // ZGL add - recN->procInfo->SetLocalType(recofs, ftype); - /* - if (ftype != "" && GetTypeKind(ftype, &size) == ikRecord) - { - String recFileName = FMain_11011981->WrkDir + "\\types.idr"; - FILE* recFile = fopen(recFileName.c_str(), "rt"); - if (recFile) - { - while (1) - { - if (!fgets(StringBuf, 1024, recFile)) break; - String str = String(StringBuf); - if (str.Pos(ftype + "=") == 1) - { - while (1) - { - if (!fgets(StringBuf, 1024, recFile)) break; - str = String(StringBuf); - if (str.Pos("end;")) break; - int pos2 = str.Pos("//"); - if (pos2) - { - String ofs = str.SubString(pos2 + 2, str.Length()); - int pos1 = str.Pos(":"); - if (pos1) - { - name = str.SubString(1, pos1 - 1); - type = str.SubString(pos1 + 1, pos2 - pos1 - 1); - recN->procInfo->AddLocal(StrToInt("$" + ofs) + recofs, 1, fname + "." + name, type); - } - } - } - } - } - fclose(recFile); - } - while (1) - { - //KB - WORD* uses = KnowledgeBase.GetTypeUses(ftype.c_str()); - int idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, ftype.c_str()); - if (uses) delete[] uses; - - if (idx == -1) break; - - idx = KnowledgeBase.TypeOffsets[idx].NamId; - MTypeInfo tInfo; - if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS, &tInfo)) - { - if (tInfo.FieldsNum) - { - char* p = tInfo.Fields; - for (int k = 0; k < tInfo.FieldsNum; k++) - { - //Scope - p++; - int elofs = *((int*)p); p += 4; - p += 4;//case - //Name - int len = *((WORD*)p); p += 2; - name = String((char*)p, len); p += len + 1; - //Type - len = *((WORD*)p); p += 2; - type = TrimTypeName(String((char*)p, len)); p += len + 1; - recN->procInfo->AddLocal(recofs + elofs, 1, fname + "." + name, type); - } - break; - } - if (tInfo.Decl != "") - { - ftype = tInfo.Decl; - } - } - } - } - */ - FillVars(); - - pnlVars->Visible = false; - lbVars->Enabled = true; - lbArgs->Enabled = true; - - bEdit->Enabled = true; - bAdd->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - bOk->Enabled = true; - - VarModified = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bCancelVarClick(TObject *Sender) { - pnlVars->Visible = false; - lbVars->Enabled = true; - lbArgs->Enabled = true; - bOk->Enabled = false; - VarModified = false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bRemoveSelectedClick(TObject *Sender) { - if (pc->ActivePage == tsVars) { - PInfoRec recN = GetInfoRec(Adr); - for (int n = lbVars->Count - 1; n >= 0; n--) { - if (lbVars->Selected[n]) { - PLOCALINFO pLocInfo = (PLOCALINFO)recN->procInfo->locals->Items[n]; - recN->procInfo->DeleteLocal(n); - } - } - FillVars(); - bEdit->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = (lbVars->Count > 0); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bAddClick(TObject *Sender) { - String line, item; - if (pc->ActivePage == tsVars) { - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FillVMTCandidates() { - if (!VmtCandidatesNum) { - for (int m = 0; m < VmtList->Count; m++) { - PVmtListRec recV = (PVmtListRec)VmtList->Items[m]; - cbVmtCandidates->Items->Add(recV->vmtName); - VmtCandidatesNum++; - } - cbMethod->Visible = (VmtCandidatesNum != 0); - cbVmtCandidates->Visible = (VmtCandidatesNum != 0); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FillType() { - BYTE callKind; - int argsBytes; - DWORD flags; - PInfoRec recN; - String line; - - mType->Clear(); - recN = GetInfoRec(Adr); - - switch (recN->kind) { - case ikConstructor: - rgFunctionKind->ItemIndex = 0; - break; - case ikDestructor: - rgFunctionKind->ItemIndex = 1; - break; - case ikProc: - rgFunctionKind->ItemIndex = 2; - break; - case ikFunc: - rgFunctionKind->ItemIndex = 3; - break; - } - flags = recN->procInfo->flags; - callKind = flags & 7; - rgCallKind->ItemIndex = callKind; - cbEmbedded->Checked = (flags & PF_EMBED); - - line = recN->MakeMultilinePrototype(Adr, &argsBytes, (cbMethod->Checked) ? cbVmtCandidates->Text : String("")); - mType->Lines->Add(line); - // No VMT - nothing to choose - if (!VmtCandidatesNum) { - cbMethod->Checked = false; - cbMethod->Visible = false; - cbVmtCandidates->Visible = false; - } - else { - if (VmtCandidatesNum == 1) - cbVmtCandidates->Text = cbVmtCandidates->Items->Strings[0]; - - if (recN->kind == ikConstructor || recN->kind == ikDestructor || (flags & PF_METHOD)) { - cbMethod->Checked = true; - if (recN->HasName()) - cbVmtCandidates->Text = ExtractClassName(recN->GetName()); - } - else { - cbMethod->Checked = false; - } - - cbMethod->Visible = true; - cbVmtCandidates->Visible = true; - } - - recN->procInfo->flags &= ~PF_ARGSIZEL; - recN->procInfo->flags &= ~PF_ARGSIZEG; - if (argsBytes > recN->procInfo->retBytes) - recN->procInfo->flags |= PF_ARGSIZEG; - if (argsBytes < recN->procInfo->retBytes) - recN->procInfo->flags |= PF_ARGSIZEL; - - lRetBytes->Caption = String(recN->procInfo->retBytes); - lArgsBytes->Caption = String(argsBytes); -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FillArgs() { - BYTE callKind; - int n, cnt, wid, maxwid, offset; - TCanvas *canvas; - PInfoRec recN; - PARGINFO argInfo; - String line; - - lbArgs->Clear(); - recN = GetInfoRec(Adr); - if (recN->procInfo->args) { - canvas = lbArgs->Canvas; - maxwid = 0; - - cnt = recN->procInfo->args->Count; - callKind = recN->procInfo->flags & 7; - - if (callKind == 1 || callKind == 3) // cdecl, stdcall - { - for (n = 0; n < cnt; n++) { - argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - line = Val2Str4(argInfo->Ndx) + " " + Val2Str2(argInfo->Size) + " "; - - if (argInfo->Name != "") - line += argInfo->Name; - else - line += "?"; - line += ":"; - if (argInfo->TypeDef != "") - line += argInfo->TypeDef; - else - line += "?"; - - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - lbArgs->Items->Add(line); - } - } - else if (callKind == 2) // pascal - { - for (n = cnt - 1; n >= 0; n--) { - argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - line = Val2Str4(argInfo->Ndx) + " " + Val2Str2(argInfo->Size) + " "; - - if (argInfo->Name != "") - line += argInfo->Name; - else - line += "?"; - line += ":"; - if (argInfo->TypeDef != "") - line += argInfo->TypeDef; - else - line += "?"; - - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - lbArgs->Items->Add(line); - } - } - else // fastcall, safecall - { - offset = recN->procInfo->bpBase; - for (n = 0; n < cnt; n++) { - argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - if (argInfo->Ndx > 2) { - offset += argInfo->Size; - continue; - } - if (argInfo->Ndx == 0) - line = " eax "; - else if (argInfo->Ndx == 1) - line = " edx "; - else if (argInfo->Ndx == 2) - line = " ecx "; - - line += Val2Str2(argInfo->Size) + " "; - - if (argInfo->Tag == 0x22) - line += "var "; - if (argInfo->Name != "") - line += argInfo->Name; - else - line += "?"; - line += ":"; - if (argInfo->TypeDef != "") - line += argInfo->TypeDef; - else - line += "?"; - - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - lbArgs->Items->Add(line); - } - for (n = 0; n < cnt; n++) { - argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - if (argInfo->Ndx <= 2) - continue; - - offset -= argInfo->Size; - line = Val2Str4(offset) + " " + Val2Str2(argInfo->Size) + " "; - - if (argInfo->Tag == 0x22) - line += "var "; - if (argInfo->Name != "") - line += argInfo->Name; - else - line += "?"; - line += ":"; - if (argInfo->TypeDef != "") - line += argInfo->TypeDef; - else - line += "?"; - - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - lbArgs->Items->Add(line); - } - } - lbArgs->ScrollWidth = maxwid + 2; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FillVars() { - int n, wid, maxwid; - TCanvas *canvas; - PInfoRec recN; - PLOCALINFO locInfo; - String line; - - lbVars->Clear(); - rgLocBase->ItemIndex = -1; - recN = GetInfoRec(Adr); - if (recN->procInfo->locals) { - rgLocBase->ItemIndex = (recN->procInfo->flags & PF_BPBASED); - - canvas = lbVars->Canvas; - maxwid = 0; - for (n = 0; n < recN->procInfo->locals->Count; n++) { - locInfo = (PLOCALINFO)recN->procInfo->locals->Items[n]; - line = Val2Str8(-locInfo->Ofs) + " " + Val2Str2(locInfo->Size) + " "; - if (locInfo->Name != "") - line += locInfo->Name; - else - line += "?"; - line += ":"; - if (locInfo->TypeDef != "") - line += locInfo->TypeDef; - else - line += "?"; - - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - lbVars->Items->Add(line); - } - lbVars->ScrollWidth = maxwid + 2; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FormClose(TObject *Sender, TCloseAction &Action) { - if (!TypModified) { - PInfoRec recN = GetInfoRec(Adr); - recN->SetName(SName); - recN->procInfo->flags = SFlags; - } - else - ProjectModified = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::cbMethodClick(TObject *Sender) { - PInfoRec recN = GetInfoRec(Adr); - if (cbMethod->Checked) { - cbVmtCandidates->Enabled = true; - recN->procInfo->flags |= PF_METHOD; - FillType(); - cbVmtCandidates->Text = ((PARGINFO)recN->procInfo->args->Items[0])->TypeDef; - } - else { - cbVmtCandidates->Enabled = false; - recN->procInfo->flags &= ~PF_METHOD; - FillType(); - cbVmtCandidates->Text = ""; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} - -// --------------------------------------------------------------------------- -void __fastcall TFEditFunctionDlg_11011981::bRemoveAllClick(TObject *Sender) { - PInfoRec recN = GetInfoRec(Adr); - if (recN->procInfo->locals) { - recN->procInfo->DeleteLocals(); - FillVars(); - bEdit->Enabled = false; - bRemoveSelected->Enabled = false; - bRemoveAll->Enabled = false; - } -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/EditFunctionDlg.h b/Sources/Forms/EditFunctionDlg.h deleted file mode 100644 index 8ddd30d..0000000 --- a/Sources/Forms/EditFunctionDlg.h +++ /dev/null @@ -1,91 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef EditFunctionDlgH -#define EditFunctionDlgH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include "Main.h" - -// ---------------------------------------------------------------------------- -class TFEditFunctionDlg_11011981 : public TForm { -__published: - TPanel *Panel1; - TButton *bEdit; - TButton *bAdd; - TButton *bRemoveSelected; - TPageControl *pc; - TTabSheet *tsArgs; - TListBox *lbArgs; - TTabSheet *tsVars; - TListBox *lbVars; - TPanel *pnlVars; - TRadioGroup *rgLocBase; - TLabeledEdit *edtVarOfs; - TLabeledEdit *edtVarSize; - TLabeledEdit *edtVarName; - TLabeledEdit *edtVarType; - TButton *bApplyVar; - TButton *bCancelVar; - TTabSheet *tsType; - TCheckBox *cbEmbedded; - TMemo *mType; - TRadioGroup *rgCallKind; - TButton *bApplyType; - TButton *bCancelType; - TRadioGroup *rgFunctionKind; - TButton *bOk; - TComboBox *cbVmtCandidates; - TCheckBox *cbMethod; - TLabel *Label1; - TLabel *lRetBytes; - TLabel *Label2; - TLabel *lArgsBytes; - TLabeledEdit *lEndAdr; - TLabeledEdit *lStackSize; - TButton *bRemoveAll; - - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall bEditClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall pcChange(TObject *Sender); - void __fastcall lbVarsClick(TObject *Sender); - void __fastcall bCancelVarClick(TObject *Sender); - void __fastcall bApplyVarClick(TObject *Sender); - void __fastcall bRemoveSelectedClick(TObject *Sender); - void __fastcall bAddClick(TObject *Sender); - void __fastcall bApplyTypeClick(TObject *Sender); - void __fastcall bCancelTypeClick(TObject *Sender); - void __fastcall bOkClick(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall cbMethodClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - void __fastcall bRemoveAllClick(TObject *Sender); - -private: - bool TypModified; - bool VarModified; - int ArgEdited; - int VmtCandidatesNum; - int StackSize; - DWORD SFlags; - String SName; - - void __fastcall FillVMTCandidates(); - void __fastcall FillType(); - void __fastcall FillArgs(); - void __fastcall FillVars(); - -public: - DWORD Adr; - DWORD EndAdr; - - virtual __fastcall TFEditFunctionDlg_11011981(TComponent* AOwner); -}; - -// ---------------------------------------------------------------------------- -extern PACKAGE TFEditFunctionDlg_11011981 *FEditFunctionDlg_11011981; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/Explorer.cpp b/Sources/Forms/Explorer.cpp deleted file mode 100644 index 23920fd..0000000 --- a/Sources/Forms/Explorer.cpp +++ /dev/null @@ -1,321 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Explorer.h" -#include "Main.h" -#include "Misc.h" -#include -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" - -extern MDisasm Disasm; -extern DWORD ImageBase; -extern DWORD ImageSize; -extern DWORD TotalSize; -extern DWORD CodeBase; -extern DWORD CodeSize; -extern BYTE *Image; -extern BYTE *Code; - -extern char StringBuf[MAXSTRBUFFER]; -extern PInfoRec *Infos; - -TFExplorer_11011981 *FExplorer_11011981; - -// --------------------------------------------------------------------------- -__fastcall TFExplorer_11011981::TFExplorer_11011981(TComponent* Owner) : TForm(Owner) { - WAlign = 0; - DefineAs = 0; - Adr = 0; - lbCode->Clear(); - lbData->Clear(); - lbString->Clear(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::ShowCode(DWORD fromAdr, int maxBytes) { - int pos; - DISINFO DisInfo; - char disLine[100]; - - lbCode->Clear(); - - pos = Adr2Pos(fromAdr); - if (pos == -1) - return; - - Adr = fromAdr; - DWORD curAdr = Adr; - - for (int n = 0; n < maxBytes;) { - int instrLen = Disasm.Disassemble(Code + pos, (__int64)curAdr, &DisInfo, disLine); - // if (!instrLen) break; - if (!instrLen) { - instrLen = 1; - lbCode->Items->Add(Val2Str8(curAdr) + " ???"); - } - else { - lbCode->Items->Add(Val2Str8(curAdr) + " " + disLine); - } - if (n + instrLen > maxBytes) - break; - if (pos + instrLen >= CodeSize) - break; - pos += instrLen; - curAdr += instrLen; - n += instrLen; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::ShowData(DWORD fromAdr, int maxBytes) { - BYTE b; - int n, k, m, pos; - float singleVal; - double doubleVal; - long double extendedVal; - double realVal; - Comp compVal; - String line1, line2; - - lbData->Clear(); - - pos = Adr2Pos(fromAdr); - if (pos == -1) - return; - - Adr = fromAdr; - DWORD curAdr = Adr; - - switch (rgDataViewStyle->ItemIndex) { - // Hex (default) - case 0: - for (n = 0, k = 0; n < maxBytes; n++) { - if (pos > ImageSize) - break; - if (!k) { - line1 = Val2Str8(curAdr) + " "; - line2 = " "; - } - line1 += " " + Val2Str2(Image[pos]); - b = Image[pos]; - if (b < ' ') - b = ' '; - line2 += String((char)b); - k++; - if (k == 16) { - lbData->Items->Add(line1 + line2); - curAdr += 16; - k = 0; - } - pos++; - } - if (k > 0 && k < 16) { - for (m = k; m < 16; m++) - line1 += " "; - lbData->Items->Add(line1 + line2); - } - break; - // Single = float - case 1: - singleVal = 0; - memmove((void*)&singleVal, Image + pos, 4); - line1 = Val2Str8(curAdr) + " " + FloatToStr(singleVal); - lbData->Items->Add(line1); - break; - // Double = doulbe - case 2: - doubleVal = 0; - memmove((void*)&doubleVal, Image + pos, 8); - line1 = Val2Str8(curAdr) + " " + FloatToStr(doubleVal); - lbData->Items->Add(line1); - break; - // Extended = long double - case 3: - try { - extendedVal = 0; - memmove((void*)&extendedVal, Image + pos, 10); - line1 = Val2Str8(curAdr) + " " + FloatToStr(extendedVal); - } - catch (Exception &E) { - line1 = "Impossible!"; - } - lbData->Items->Add(line1); - break; - // Real = double - case 4: - realVal = 0; - memmove((void*)&realVal, Image + pos, 4); - line1 = Val2Str8(curAdr) + " " + FloatToStr(realVal); - lbData->Items->Add(line1); - break; - // Comp = Comp - case 5: - compVal = 0; - memmove((void*)&compVal, Image + pos, 8); - line1 = Val2Str8(curAdr) + " " + FloatToStr(compVal); - lbData->Items->Add(line1); - break; - } - lbData->Update(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::ShowString(DWORD fromAdr, int maxBytes) { - int len, size, pos; - DWORD adr, resid; - char *tmpBuf; - HINSTANCE hInst; - String str; - WideString wStr; - char buf[1024]; - - lbString->Clear(); - - pos = Adr2Pos(fromAdr); - if (pos == -1) - return; - - switch (rgStringViewStyle->ItemIndex) { - case 0: // PAnsiChar - len = strlen((char*)(Image + pos)); - if (len < 0) - len = 0; - if (len > maxBytes) - len = maxBytes; - str = TransformString(Image + pos, len); - break; - case 1: // PWideChar - len = wcslen((wchar_t*)(Image + pos)); - if (len < 0) - len = 0; - if (len > maxBytes) - len = maxBytes; - wStr = WideString((wchar_t*)(Image + pos)); - size = WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, 0, 0, 0, 0); - if (size) { - tmpBuf = new char[size + 1]; - WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, (LPSTR)tmpBuf, size, 0, 0); - str = TransformString(tmpBuf, size); - delete[]tmpBuf; - } - break; - case 2: // ShortString - len = *(Image + pos); - if (len < 0) - len = 0; - if (len > maxBytes) - len = maxBytes; - str = TransformString(Image + pos + 1, len); - break; - case 3: // AnsiString - len = *((int*)(Image + pos)); - if (len < 0) - len = 0; - if (len > maxBytes) - len = maxBytes; - str = TransformString(Image + pos + 4, len); - break; - case 4: // WideString - len = *((int*)(Image + pos + WAlign)); - if (len < 0) - len = 0; - if (len > maxBytes) - len = maxBytes; - wStr = WideString((wchar_t*)(Image + pos + WAlign + 4)); - size = WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, 0, 0, 0, 0); - if (size) { - tmpBuf = new char[size + 1]; - WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, (LPSTR)tmpBuf, size, 0, 0); - str = TransformString(tmpBuf, size); - delete[]tmpBuf; - } - break; - } - - lbString->Lines->Add(str); -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::ShowArray(DWORD fromAdr) { - /* - lbArray->Clear(); - - int pos = Adr2Pos(fromAdr); - DWORD curAdr = fromAdr; - - for (int n = 0; n < 32; n++) - { - if (pos > TotalSize) break; - DWORD Adr = *((DWORD*)(Image + pos)); - if (!IsValidImageAdr(Adr)) break; - char* p = Image + Adr2Pos(Adr); - String s = String(p); - lbArray->Items->Add(s); - pos += 4; - } - */ -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::btnDefCodeClick(TObject *Sender) { - DefineAs = DEFINE_AS_CODE; - ModalResult = mrOk; -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::btnUndefCodeClick(TObject *Sender) { - DefineAs = UNDEFINE; - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::btnDefStringClick(TObject *Sender) { - DefineAs = DEFINE_AS_STRING; - ModalResult = mrOk; -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::rgStringViewStyleClick(TObject *Sender) { - ShowString(Adr, 1024); -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::miCopy2ClipboardClick(TObject *Sender) { - TStrings* items; - - if (pc1->ActivePage == tsCode) - items = lbCode->Items; - else if (pc1->ActivePage == tsData) - items = lbData->Items; - else if (pc1->ActivePage == tsString) - items = lbString->Lines; - else if (pc1->ActivePage == tsText) - items = lbText->Items; - - Copy2Clipboard(items, 0, false); -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_ESCAPE) - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::FormShow(TObject *Sender) { - DefineAs = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::rgDataViewStyleClick(TObject *Sender) { - ShowData(Adr, 1024); -} - -// --------------------------------------------------------------------------- -void __fastcall TFExplorer_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/Explorer.h b/Sources/Forms/Explorer.h deleted file mode 100644 index 52db2e8..0000000 --- a/Sources/Forms/Explorer.h +++ /dev/null @@ -1,68 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef ExplorerH -#define ExplorerH -// --------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -// --------------------------------------------------------------------------- -#define DEFINE_AS_CODE 1 -#define DEFINE_AS_STRING 2 -#define UNDEFINE 3 - -class TFExplorer_11011981 : public TForm { -__published: // IDE-managed Components - TPageControl *pc1; - TTabSheet *tsCode; - TTabSheet *tsData; - TListBox *lbCode; - TListBox *lbData; - TTabSheet *tsString; - TRadioGroup *rgStringViewStyle; - TTabSheet *tsText; - TListBox *lbText; - TPopupMenu *pm1; - TMenuItem *miCopy2Clipboard; - TPanel *Panel2; - TRadioGroup *rgDataViewStyle; - TMemo *lbString; - TPanel *Panel3; - TButton *btnDefCode; - TButton *btnUndefCode; - TPanel *Panel1; - TButton *btnDefString; - TButton *btnUndefString; - - void __fastcall btnDefCodeClick(TObject *Sender); - void __fastcall btnUndefCodeClick(TObject *Sender); - void __fastcall rgStringViewStyleClick(TObject *Sender); - void __fastcall miCopy2ClipboardClick(TObject *Sender); - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall FormShow(TObject *Sender); - void __fastcall rgDataViewStyleClick(TObject *Sender); - void __fastcall btnDefStringClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: // User declarations - DWORD Adr; // Àäðåñ, ñ êîòîðîãî ïîêàçûâàåòñÿ èíôîðìàöèÿ - -public: // User declarations - __fastcall TFExplorer_11011981(TComponent* Owner); - void __fastcall ShowCode(DWORD fromAdr, int maxBytes); - void __fastcall ShowData(DWORD fromAdr, int maxBytes); - void __fastcall ShowString(DWORD fromAdr, int maxbytes); - void __fastcall ShowArray(DWORD fromAdr); - - int DefineAs; // 1- Define as Code, 2 - Undefine - int WAlign; // Alignment for WideString visualization -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFExplorer_11011981 *FExplorer_11011981; -// --------------------------------------------------------------------------- -#endif - \ No newline at end of file diff --git a/Sources/Forms/FindDlg.cpp b/Sources/Forms/FindDlg.cpp deleted file mode 100644 index 9541841..0000000 --- a/Sources/Forms/FindDlg.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// --------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "FindDlg.h" -#include "Misc.h" -// --------------------------------------------------------------------- -#pragma resource "*.dfm" -TFindDlg_11011981 *FindDlg_11011981; - -// --------------------------------------------------------------------- -__fastcall TFindDlg_11011981::TFindDlg_11011981(TComponent* AOwner) : TForm(AOwner) { -} - -// --------------------------------------------------------------------- -void __fastcall TFindDlg_11011981::FormShow(TObject *Sender) { - if (cbText->Items->Count) - cbText->Text = cbText->Items->Strings[0]; - ActiveControl = cbText; -} - -// --------------------------------------------------------------------------- -void __fastcall TFindDlg_11011981::cbTextEnter(TObject *Sender) { - cbText->SelectAll(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFindDlg_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/FindDlg.h b/Sources/Forms/FindDlg.h deleted file mode 100644 index 804b982..0000000 --- a/Sources/Forms/FindDlg.h +++ /dev/null @@ -1,31 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef FindDlgH -#define FindDlgH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include - -// ---------------------------------------------------------------------------- -class TFindDlg_11011981 : public TForm { -__published: - TButton *OKBtn; - TButton *CancelBtn; - TBevel *Bevel1; - TComboBox *cbText; - TLabel *Label1; - - void __fastcall FormShow(TObject *Sender); - void __fastcall cbTextEnter(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: -public: - virtual __fastcall TFindDlg_11011981(TComponent* AOwner); -}; - -// ---------------------------------------------------------------------------- -extern PACKAGE TFindDlg_11011981 *FindDlg_11011981; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/Hex2Double.cpp b/Sources/Forms/Hex2Double.cpp deleted file mode 100644 index a72ae2e..0000000 --- a/Sources/Forms/Hex2Double.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// --------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Hex2Double.h" -#include -// --------------------------------------------------------------------- -#pragma resource "*.dfm" -TFHex2DoubleDlg_11011981 *FHex2DoubleDlg_11011981; - -// --------------------------------------------------------------------- -__fastcall TFHex2DoubleDlg_11011981::TFHex2DoubleDlg_11011981(TComponent* AOwner) : TForm(AOwner) { -} - -// --------------------------------------------------------------------- -void __fastcall TFHex2DoubleDlg_11011981::FormShow(TObject *Sender) { - rgDataViewStyle->ItemIndex = 0; - PrevIdx = 0; - edtValue->Text = ""; - if (edtValue->CanFocus()) - ActiveControl = edtValue; -} - -// --------------------------------------------------------------------------- -void __fastcall TFHex2DoubleDlg_11011981::edtValueEnter(TObject *Sender) { - edtValue->SelectAll(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFHex2DoubleDlg_11011981::Str2Binary(String AStr) { - BYTE c; - int val, pos, n; - char *src; - - src = AnsiString(AStr).c_str(); - memset(BinData, 0, 16); - n = 0; - - while (1) { - c = *src; - if (!c) - break; - if (c != ' ') { - sscanf(src, "%X", &val); - BinData[n] = val; - n++; - while (1) { - c = *src; - if (!c || c == ' ') - break; - src++; - } - if (!c) - break; - } - src++; - } -} - -// --------------------------------------------------------------------------- -String __fastcall TFHex2DoubleDlg_11011981::Binary2Str(int BytesNum) { - String result = ""; - for (int n = 0; n < BytesNum; n++) { - if (n) - result += " "; - result += Val2Str2(BinData[n]); - } - return result; -} - -// --------------------------------------------------------------------------- -void __fastcall TFHex2DoubleDlg_11011981::rgDataViewStyleClick(TObject *Sender) { - int n; - float singleVal; - double doubleVal; - long double extendedVal; - double realVal; - Comp compVal; - String result; - - if (edtValue->Text == "") { - PrevIdx = rgDataViewStyle->ItemIndex; - return; - } - if (rgDataViewStyle->ItemIndex == PrevIdx) - return; - - result = edtValue->Text; - try { - if (rgDataViewStyle->ItemIndex == 0) // Hex - { - memset((void*)BinData, 0, 16); - if (PrevIdx == FT_SINGLE) { - singleVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &singleVal, 4); - result = Binary2Str(4); - } - else if (PrevIdx == FT_DOUBLE) { - doubleVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &doubleVal, 8); - result = Binary2Str(8); - } - else if (PrevIdx == FT_EXTENDED) { - extendedVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &extendedVal, 10); - result = Binary2Str(10); - } - else if (PrevIdx == FT_REAL) { - realVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &realVal, 4); - result = Binary2Str(4); - } - else if (PrevIdx == FT_COMP) { - compVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &compVal, 8); - result = Binary2Str(8); - } - } - else { - if (PrevIdx == 0) { - Str2Binary(edtValue->Text); - } - else if (PrevIdx == FT_SINGLE) { - singleVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &singleVal, 4); - } - else if (PrevIdx == FT_DOUBLE) { - doubleVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &doubleVal, 8); - } - else if (PrevIdx == FT_EXTENDED) { - extendedVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &extendedVal, 10); - } - else if (PrevIdx == FT_REAL) { - realVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &realVal, 4); - } - else if (PrevIdx == FT_COMP) { - compVal = StrToFloat(edtValue->Text); - memmove((void*)BinData, &compVal, 8); - } - if (rgDataViewStyle->ItemIndex == FT_SINGLE) { - singleVal = 0; - memmove((void*)&singleVal, BinData, 4); - result = FloatToStr(singleVal); - } - else if (rgDataViewStyle->ItemIndex == FT_DOUBLE) { - doubleVal = 0; - memmove((void*)&doubleVal, BinData, 8); - result = FloatToStr(doubleVal); - } - else if (rgDataViewStyle->ItemIndex == FT_EXTENDED) { - extendedVal = 0; - memmove((void*)&extendedVal, BinData, 10); - result = FloatToStr(extendedVal); - } - else if (rgDataViewStyle->ItemIndex == FT_REAL) { - realVal = 0; - memmove((void*)&realVal, BinData, 4); - result = FloatToStr(realVal); - } - else if (rgDataViewStyle->ItemIndex == FT_COMP) { - compVal = 0; - memmove((void*)&compVal, BinData, 8); - result = FloatToStr(compVal); - } - } - } - catch (Exception &E) { - result = "Impossible!"; - } - PrevIdx = rgDataViewStyle->ItemIndex; - edtValue->Text = result; -} - -// --------------------------------------------------------------------------- -void __fastcall TFHex2DoubleDlg_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/Hex2Double.h b/Sources/Forms/Hex2Double.h deleted file mode 100644 index 6c122d5..0000000 --- a/Sources/Forms/Hex2Double.h +++ /dev/null @@ -1,36 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef Hex2DoubleH -#define Hex2DoubleH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include -#include "Misc.h" - -// ---------------------------------------------------------------------------- -class TFHex2DoubleDlg_11011981 : public TForm { -__published: - TRadioGroup *rgDataViewStyle; - TLabeledEdit *edtValue; - - void __fastcall FormShow(TObject *Sender); - void __fastcall edtValueEnter(TObject *Sender); - void __fastcall rgDataViewStyleClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: - int PrevIdx; - BYTE BinData[16]; - - void __fastcall Str2Binary(String AStr); - String __fastcall Binary2Str(int BytesNum); - -public: - virtual __fastcall TFHex2DoubleDlg_11011981(TComponent* AOwner); -}; - -// ---------------------------------------------------------------------------- -extern PACKAGE TFHex2DoubleDlg_11011981 *FHex2DoubleDlg_11011981; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/IdcSplitSize.cpp b/Sources/Forms/IdcSplitSize.cpp deleted file mode 100644 index 0bad0fd..0000000 --- a/Sources/Forms/IdcSplitSize.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// --------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "IdcSplitSize.h" -// --------------------------------------------------------------------- -#pragma resource "*.dfm" -extern int SplitSize; - -TFIdcSplitSize *FIdcSplitSize; - -// --------------------------------------------------------------------- -__fastcall TFIdcSplitSize::TFIdcSplitSize(TComponent* AOwner) : TForm(AOwner) { - Caption = "Split size: 1 Mbyte"; -} - -// --------------------------------------------------------------------- -void __fastcall TFIdcSplitSize::OKBtnClick(TObject *Sender) { - SplitSize = (1 << (tbSplitSize->Position + 19)); // MBytes - ModalResult = mrOk; -} - -// --------------------------------------------------------------------------- -void __fastcall TFIdcSplitSize::CancelBtnClick(TObject *Sender) { - SplitSize = 0; - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFIdcSplitSize::tbSplitSizeChange(TObject *Sender) { - Caption = "Split size: " + String(tbSplitSize->Position) + " MByte"; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/IdcSplitSize.h b/Sources/Forms/IdcSplitSize.h deleted file mode 100644 index e4b7a61..0000000 --- a/Sources/Forms/IdcSplitSize.h +++ /dev/null @@ -1,31 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef IdcSplitSizeH -#define IdcSplitSizeH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include -#include - -// ---------------------------------------------------------------------------- -class TFIdcSplitSize : public TForm { -__published: - TButton *OKBtn; - TButton *CancelBtn; - TBevel *Bevel1; - TTrackBar *tbSplitSize; - - void __fastcall OKBtnClick(TObject *Sender); - void __fastcall CancelBtnClick(TObject *Sender); - void __fastcall tbSplitSizeChange(TObject *Sender); - -private: -public: - virtual __fastcall TFIdcSplitSize(TComponent* AOwner); -}; - -// ---------------------------------------------------------------------------- -extern PACKAGE TFIdcSplitSize *FIdcSplitSize; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/InputDlg.cpp b/Sources/Forms/InputDlg.cpp deleted file mode 100644 index cbb324c..0000000 --- a/Sources/Forms/InputDlg.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// --------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "InputDlg.h" -#include "Misc.h" -// --------------------------------------------------------------------- -#pragma resource "*.dfm" -TFInputDlg_11011981 *FInputDlg_11011981; - -// --------------------------------------------------------------------- -__fastcall TFInputDlg_11011981::TFInputDlg_11011981(TComponent* AOwner) : TForm(AOwner) { -} - -// --------------------------------------------------------------------- -void __fastcall TFInputDlg_11011981::FormShow(TObject *Sender) { - if (edtName->CanFocus()) - ActiveControl = edtName; -} - -// --------------------------------------------------------------------------- -void __fastcall TFInputDlg_11011981::edtNameEnter(TObject *Sender) { - edtName->SelectAll(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFInputDlg_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/InputDlg.h b/Sources/Forms/InputDlg.h deleted file mode 100644 index 3bb29c5..0000000 --- a/Sources/Forms/InputDlg.h +++ /dev/null @@ -1,29 +0,0 @@ -// ---------------------------------------------------------------------------- -#ifndef InputDlgH -#define InputDlgH -// ---------------------------------------------------------------------------- -#include -#include -#include -#include - -// ---------------------------------------------------------------------------- -class TFInputDlg_11011981 : public TForm { -__published: - TButton *OKBtn; - TButton *CancelBtn; - TLabeledEdit *edtName; - - void __fastcall FormShow(TObject *Sender); - void __fastcall edtNameEnter(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: -public: - virtual __fastcall TFInputDlg_11011981(TComponent* AOwner); -}; - -// ---------------------------------------------------------------------------- -extern PACKAGE TFInputDlg_11011981 *FInputDlg_11011981; -// ---------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/KBViewer.cpp b/Sources/Forms/KBViewer.cpp deleted file mode 100644 index 6861aae..0000000 --- a/Sources/Forms/KBViewer.cpp +++ /dev/null @@ -1,346 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "KBViewer.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" - -#include "Disasm.h" -#include "KnowledgeBase.h" -#include "Main.h" -#include "Misc.h" - -extern DWORD CodeBase; -extern DWORD CurProcAdr; -extern DWORD CurUnitAdr; -extern MDisasm Disasm; -extern BYTE *Code; -extern PInfoRec *Infos; -extern MKnowledgeBase KnowledgeBase; -extern TList *VmtList; -extern TList *OwnTypeList; - -TFKBViewer_11011981 *FKBViewer_11011981; - -// --------------------------------------------------------------------------- -__fastcall TFKBViewer_11011981::TFKBViewer_11011981(TComponent* Owner) : TForm(Owner) { - UnitsNum = 0; - CurrIdx = -1; - CurrAdr = 0; - FromIdx = 0; - ToIdx = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::FormCreate(TObject *Sender) { - lbIDR->Canvas->Font->Assign(lbIDR->Font); - lbKB->Canvas->Font->Assign(lbKB->Font); - ScaleForm(this); -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::ShowCode(DWORD adr, int idx) { - bool outfixup; - int n, m, wid, maxwid, row; - int _firstProcIdx, _lastProcIdx; - DWORD Val, Adr; - TCanvas* canvas; - String line; - DISINFO DisInfo; - char disLine[100]; - - CurrIdx = idx; - CurrAdr = adr; - edtCurrIdx->Text = String(CurrIdx); - lPosition->Caption = String(CurrIdx - Position); - - lbIDR->Clear(); - canvas = lbIDR->Canvas; - maxwid = 0; - for (m = 0; m < FMain_11011981->lbCode->Count; m++) { - line = FMain_11011981->lbCode->Items->Strings[m]; - // Ignore first byte (for symbol <) - int _bytes = line.Length() - 1; - // If instruction, ignore flags (last byte) - if (m) - _bytes--; - // Extract original instruction - line = line.SubString(2, _bytes); - // For first row add prefix IDR: - if (!m) - line = "IDR:" + line; - lbIDR->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - lbIDR->ScrollWidth = maxwid + 2; - - lbKB->Clear(); - row = 0; - MProcInfo aInfo; - MProcInfo *pInfo = &aInfo; - maxwid = 0; - if (KnowledgeBase.GetProcInfo(CurrIdx, INFO_DUMP, pInfo)) { - cbUnits->Text = KnowledgeBase.GetModuleName(pInfo->ModuleID); - KnowledgeBase.GetProcIdxs(pInfo->ModuleID, &_firstProcIdx, &_lastProcIdx); - lblKbIdxs->Caption = String(_firstProcIdx) + " - " + String(_lastProcIdx); - - canvas = lbKB->Canvas; - - line = "KB:" + pInfo->ProcName; - lbKB->Items->Add(line); - row++; - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - - int instrLen, pos = 0; - DWORD curAdr = adr; - - if (pInfo->FixupNum) { - char *p = pInfo->Dump + 2 * pInfo->DumpSz; - - for (n = 0; n < pInfo->FixupNum; n++) { - char fixupType = *p; - p++; - int fixupOfs = *((DWORD*)p); - p += 4; - WORD len = *((WORD*)p); - p += 2; - String fixupName = String(p, len); - p += len + 1; - - while (pos <= fixupOfs && pos < pInfo->DumpSz) { - instrLen = Disasm.Disassemble(pInfo->Dump + pos, (__int64)curAdr, &DisInfo, disLine); - if (!instrLen) { - // return; - lbKB->Items->Add(Val2Str8(curAdr) + " ???"); - row++; - pos++; - curAdr++; - continue; - } - - BYTE op = Disasm.GetOp(DisInfo.Mnem); - line = Val2Str8(curAdr) + " " + disLine; - outfixup = false; - if (pos + instrLen > fixupOfs) { - if (DisInfo.Call) { - line = Val2Str8(curAdr) + " call "; - outfixup = true; - } - else if (op == OP_JMP) - line = Val2Str8(curAdr) + " jmp "; - else - line += ";"; - if (!SameText(fixupName, pInfo->ProcName)) { - line += fixupName; - } - else { - Val = *((DWORD*)(Code + Adr2Pos(CurrAdr) + fixupOfs)); - if (fixupType == 'J') - Adr = CurrAdr + fixupOfs + Val + 4; - else - Adr = Val; - - line += Val2Str8(Adr); - } - } - - lbKB->Items->Add(line); - if (outfixup) - lbKB->Selected[row] = true; - row++; - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - - pos += instrLen; - curAdr += instrLen; - } - } - } - while (pos < pInfo->DumpSz) { - instrLen = Disasm.Disassemble(pInfo->Dump + pos, (__int64)curAdr, &DisInfo, disLine); - if (!instrLen) { - lbKB->Items->Add(Val2Str8(curAdr) + " ???"); - pos++; - curAdr++; - continue; - } - line = Val2Str8(curAdr) + " " + disLine; - lbKB->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - - pos += instrLen; - curAdr += instrLen; - } - } - lbKB->ScrollWidth = maxwid + 2; - lbKB->TopIndex = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::bPrevClick(TObject *Sender) { - if (CurrIdx != -1) - ShowCode(CurrAdr, CurrIdx - 1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::bNextClick(TObject *Sender) { - if (CurrIdx != -1) - ShowCode(CurrAdr, CurrIdx + 1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::btnOkClick(TObject *Sender) { - int m, k1, k2, ap, pos, pos1, pos2, Idx, val; - DWORD adr; - MProcInfo aInfo; - MProcInfo *pInfo = &aInfo; - PInfoRec recN; - String kbName, idrName, kbLine, idrLine; - - if (KnowledgeBase.GetProcInfo(CurrIdx, INFO_DUMP | INFO_ARGS, pInfo)) { - adr = CurProcAdr; - ap = Adr2Pos(adr); - if (ap < 0) - return; - recN = GetInfoRec(adr); - if (!recN) - return; - recN->procInfo->DeleteArgs(); - FMain_11011981->StrapProc(ap, CurrIdx, pInfo, false, FMain_11011981->EstimateProcSize(CurProcAdr)); - // Strap all selected items (in IDR list box) - if (lbKB->SelCount == lbIDR->SelCount) { - k1 = 0; - k2 = 0; - for (m = 0; m < lbKB->SelCount; m++) { - kbLine = ""; - idrLine = ""; - for (; k1 < lbKB->Items->Count; k1++) { - if (lbKB->Selected[k1]) { - kbLine = lbKB->Items->Strings[k1]; - k1++; - break; - } - } - for (; k2 < lbIDR->Items->Count; k2++) { - if (lbIDR->Selected[k2]) { - idrLine = lbIDR->Items->Strings[k2]; - k2++; - break; - } - } - if (kbLine != "" && idrLine != "") { - pos1 = kbLine.Pos("call"); - pos2 = idrLine.Pos("call"); - if (pos1 && pos2) { - kbName = kbLine.SubString(pos1 + 4, kbLine.Length()).Trim(); - idrName = idrLine.SubString(pos2 + 4, idrLine.Length()).Trim(); - pos = idrName.Pos(";"); - if (pos) - idrName = idrName.SubString(1, pos - 1); - adr = 0; - if (TryStrToInt(String("$") + idrName, val)) - adr = val; - ap = Adr2Pos(adr); - if (kbName != "" && ap >= 0) { - recN = GetInfoRec(adr); - recN->procInfo->DeleteArgs(); - - WORD *uses = KnowledgeBase.GetModuleUses(KnowledgeBase.GetModuleID(AnsiString(cbUnits->Text).c_str())); - Idx = KnowledgeBase.GetProcIdx(uses, AnsiString(kbName).c_str(), Code + ap); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) - FMain_11011981->StrapProc(ap, Idx, pInfo, true, pInfo->DumpSz); - } - } - else { - Idx = KnowledgeBase.GetProcIdx(uses, AnsiString(kbName).c_str(), 0); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) - FMain_11011981->StrapProc(ap, Idx, pInfo, false, FMain_11011981->EstimateProcSize(adr)); - } - } - } - } - } - } - } - } - FMain_11011981->RedrawCode(); - FMain_11011981->ShowUnitItems(FMain_11011981->GetUnit(CurUnitAdr), FMain_11011981->lbUnitItems->TopIndex, FMain_11011981->lbUnitItems->ItemIndex); - } - Close(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::btnCancelClick(TObject *Sender) { - Close(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::edtCurrIdxChange(TObject *Sender) { - try { - ShowCode(CurrAdr, StrToInt(edtCurrIdx->Text)); - } - catch (Exception &exception) { - Application->ShowException(&exception); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::cbUnitsChange(TObject *Sender) { - WORD _moduleID; - int k, _firstProcIdx, _lastProcIdx, _idx; - MProcInfo _aInfo; - MProcInfo *_pInfo = &_aInfo; - - Position = -1; - _moduleID = KnowledgeBase.GetModuleID(AnsiString(cbUnits->Text).c_str()); - if (_moduleID != 0xFFFF) { - if (KnowledgeBase.GetProcIdxs(_moduleID, &_firstProcIdx, &_lastProcIdx)) { - edtCurrIdx->Text = String(_firstProcIdx); - lblKbIdxs->Caption = String(_firstProcIdx) + " - " + String(_lastProcIdx); - for (k = _firstProcIdx; k <= _lastProcIdx; k++) { - _idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(_idx)) { - if (KnowledgeBase.GetProcInfo(_idx, INFO_DUMP | INFO_ARGS, _pInfo)) { - if (MatchCode(Code + Adr2Pos(CurProcAdr), _pInfo)) { - edtCurrIdx->Text = String(_idx); - Position = _idx; - break; - } - } - } - } - } - } - if (Position == -1) - ShowCode(CurProcAdr, _firstProcIdx); - else - ShowCode(CurProcAdr, Position); -} - -// --------------------------------------------------------------------------- -void __fastcall TFKBViewer_11011981::FormShow(TObject *Sender) { - if (!UnitsNum) { - for (int n = 0; n < KnowledgeBase.ModuleCount; n++) { - int ID = KnowledgeBase.ModuleOffsets[n].NamId; - const BYTE *p = KnowledgeBase.GetKBCachePtr(KnowledgeBase.ModuleOffsets[ID].Offset, KnowledgeBase.ModuleOffsets[ID].Size); - cbUnits->Items->Add(String((char*)(p + 4))); - UnitsNum++; - } - } -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/KBViewer.h b/Sources/Forms/KBViewer.h deleted file mode 100644 index f794128..0000000 --- a/Sources/Forms/KBViewer.h +++ /dev/null @@ -1,57 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef KBViewerH -#define KBViewerH -// --------------------------------------------------------------------------- -#include -#include -#include -#include - -// --------------------------------------------------------------------------- -class TFKBViewer_11011981 : public TForm { -__published: // IDE-managed Components - TListBox *lbKB; - TListBox *lbIDR; - TPanel *Panel3; - TButton *bPrev; - TButton *bNext; - TButton *btnOk; - TButton *btnCancel; - TLabel *lPosition; - TSplitter *Splitter1; - TEdit *edtCurrIdx; - TLabel *lKBIdx; - TPanel *Panel1; - TComboBox *cbUnits; - TLabel *Label1; - TLabel *lblKbIdxs; - - void __fastcall bPrevClick(TObject *Sender); - void __fastcall bNextClick(TObject *Sender); - void __fastcall btnOkClick(TObject *Sender); - void __fastcall btnCancelClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - void __fastcall edtCurrIdxChange(TObject *Sender); - void __fastcall cbUnitsChange(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - -private: // User declarations - int UnitsNum; - int CurrIdx; - DWORD CurrAdr; - -public: // User declarations - int Position; - DWORD FromIdx; // First Unit idx - DWORD ToIdx; // Last Unit idx - - __fastcall TFKBViewer_11011981(TComponent* Owner); - void __fastcall ShowCode(DWORD adr, int idx); -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFKBViewer_11011981 *FKBViewer_11011981; -// --------------------------------------------------------------------------- -#endif - \ No newline at end of file diff --git a/Sources/Forms/Legend.cpp b/Sources/Forms/Legend.cpp deleted file mode 100644 index 5534eca..0000000 --- a/Sources/Forms/Legend.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Legend.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" -TFLegend_11011981 *FLegend_11011981; - -// --------------------------------------------------------------------------- -__fastcall TFLegend_11011981::TFLegend_11011981(TComponent* Owner) : TForm(Owner) { - lblUnitStd->Font->Color = (TColor)0xC08000; // blue - lblUnitUser->Font->Color = (TColor)0x00B000; // green - lblUnitTrivial->Font->Color = (TColor)0x0000B0; // brown - lblUnitUserUnk->Font->Color = (TColor)0x8080FF; // red -} - -// --------------------------------------------------------------------------- -void __fastcall TFLegend_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (VK_ESCAPE == Key) - Close(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFLegend_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/Legend.h b/Sources/Forms/Legend.h deleted file mode 100644 index bc5e8c4..0000000 --- a/Sources/Forms/Legend.h +++ /dev/null @@ -1,41 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef LegendH -#define LegendH -// --------------------------------------------------------------------------- -#include -#include -#include - -// --------------------------------------------------------------------------- -class TFLegend_11011981 : public TForm { -__published: // IDE-managed Components - TGroupBox *gb1; - TLabel *Label1; - TLabel *Label2; - TLabel *Label3; - TLabel *Label5; - TLabel *lblUnitStd; - TLabel *lblUnitUser; - TLabel *lblUnitTrivial; - TLabel *lblUnitUserUnk; - TGroupBox *gb2; - TLabel *Label4; - TLabel *Label6; - TLabel *Label7; - TLabel *lblInit; - TLabel *lblFin; - TLabel *lblUnk; - TButton *btnOK; - - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall FormCreate(TObject *Sender); - -private: // User declarations -public: // User declarations - __fastcall TFLegend_11011981(TComponent* Owner); -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFLegend_11011981 *FLegend_11011981; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/Main.cpp b/Sources/Forms/Main.cpp deleted file mode 100644 index fd39f2e..0000000 --- a/Sources/Forms/Main.cpp +++ /dev/null @@ -1,18894 +0,0 @@ -// --------------------------------------------------------------------------- -// #define NO_WIN32_LEAN_AND_MEAN -#include -#pragma hdrstop - -/* - #include "SyncObjs.hpp" - #include - #include - #include - #include - #include - */ - -#include -#include - -#include "Main.h" -#include "Misc.h" -#include "Threads.h" -#include "ProgressBar.h" -#include "TypeInfo2.h" -#include "StringInfo.h" -#include "StrUtils.hpp" -#include "FindDlg.h" -#include "InputDlg.h" -#include "Disasm.h" -#include "Explorer.h" -#include "KBViewer.h" -#include "EditFunctionDlg.h" -#include "EditFieldsDlg.h" -#include "AboutDlg.h" -#include "Legend.h" -#include "IDCGen.h" -#include "IdcSplitSize.h" -#include "Decompiler.h" -#include "Hex2Double.h" -#include "Plugins.h" -#include "ActiveProcesses.h" -/* - //----Highlighting----------------------------------------------------------- - #include "Highlight.h" - DWORD DelphiLbId; - int DelphiThemesCount; - //----Highlighting----------------------------------------------------------- - */ -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" -// #pragma resource "idr_manifest.res" - -// --------------------------------------------------------------------------- -// as statistics of analysis flow -// unsigned long stat_GetClassAdr_calls = 0; -// unsigned long stat_GetClassAdr_adds = 0; -// --------------------------------------------------------------------------- -String IDRVersion = "01.04.2017"; -// --------------------------------------------------------------------------- -SysProcInfo SysProcs[] = { {"@HandleFinally", 0}, {"@HandleAnyException", 0}, {"@HandleOnException", 0}, {"@HandleAutoException", 0}, {"@RunError", 0}, - // {"@Halt", 0}, - {"@Halt0", 0}, {"@AbstractError", 0}, {0, 0}}; - -SysProcInfo SysInitProcs[] = { {"@InitExe", 0}, {"@InitLib", 0}, {0, 0}}; -// Image Code -// |===========|======================================| -// ImageBase CodeBase -// --------------------------------------------------------------------------- -char StringBuf[MAXSTRBUFFER]; // Buffer to make string - -extern char* Reg32Tab[8]; -extern char* Reg16Tab[8]; -extern char* Reg8Tab[8]; -extern char* SegRegTab[8]; -extern char* RepPrefixTab[4]; - -extern RegClassInfo RegClasses[]; - -int dummy = 0; // for debugging purposes!!! - -MDisasm Disasm; // ДизаÑÑемблер Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°Ñ‚Ð¾Ñ€Ð° кода -MKnowledgeBase KnowledgeBase; -TResourceInfo *ResInfo = 0; // Information about forms -int CodeHistorySize; // Current size of Code navigation History Array -int CodeHistoryPtr; // Curent pointer of Code navigation History Array -int CodeHistoryMax; // Max pointer position of Code navigation History Array (for ->) -DynamicArrayCodeHistory; // Code navigation History Array - -TAnalyzeThread *AnalyzeThread = 0; // Поток Ð´Ð»Ñ Ñ„Ð¾Ð½Ð¾Ð²Ð¾Ð³Ð¾ анализа кода -int AnalyzeThreadRetVal = 0; -bool SourceIsLibrary = false; -bool ClassTreeDone; -bool ProjectModified = false; -bool UserKnowledgeBase = false; -bool SplitIDC = false; -int SplitSize = 0; -// Common variables -String IDPFile; -int MaxBufLen; // МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° буфера (Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸) -int DelphiVersion; -DWORD EP; -DWORD ImageBase; -DWORD ImageSize; -DWORD TotalSize; // Size of sections CODE + DATA -DWORD CodeBase; -DWORD CodeSize; -DWORD CodeStart; -DWORD DataBase = 0; -DWORD DataSize = 0; -DWORD DataStart = 0; -BYTE *Image = 0; -DWORD *Flags = 0; // flags for used data -PInfoRec *Infos = 0; // Array of pointers to store items data -TStringList *BSSInfos = 0; // Data from BSS -BYTE *Code = 0; -BYTE *Data = 0; - -TList *ExpFuncList; // Exported functions list (temporary) -TList *ImpFuncList; // Imported functions list (temporary) -TStringList *ImpModuleList; // Imported modules list (temporary) -TList *SegmentList; // Information about Image Segments -TList *VmtList; // VMT list - -// Units -int UnitsNum = 0; -TList *Units = 0; -int UnitSortField = 0; // 0 - by address, 1 - by initialization order, 2 - by name -// Types -TList *OwnTypeList = 0; -int RTTISortField = 0; // 0 - by address, 1 - by initialization order, 2 - by name - -DWORD CurProcAdr; -int CurProcSize; -String SelectedAsmItem = ""; // Selected item in Asm Listing -String SelectedSourceItem = ""; // Selected item in Source Code -DWORD CurUnitAdr; -DWORD HInstanceVarAdr; -DWORD LastTls; // Last bust index Tls shows how many ThreadVars in program -int Reserved; -int LastResStrNo = 0; // Last ResourceStringNo -DWORD CtdRegAdr; // Procedure CtdRegAdr address - -int VmtSelfPtr = 0; -int VmtIntfTable = 0; -int VmtAutoTable = 0; -int VmtInitTable = 0; -int VmtTypeInfo = 0; -int VmtFieldTable = 0; -int VmtMethodTable = 0; -int VmtDynamicTable = 0; -int VmtClassName = 0; -int VmtInstanceSize = 0; -int VmtParent = 0; -int VmtEquals = 0; -int VmtGetHashCode = 0; -int VmtToString = 0; -int VmtSafeCallException = 0; -int VmtAfterConstruction = 0; -int VmtBeforeDestruction = 0; -int VmtDispatch = 0; -int VmtDefaultHandler = 0; -int VmtNewInstance = 0; -int VmtFreeInstance = 0; -int VmtDestroy = 0; - -// as -// class addresses cache -typedef std::map< const String, DWORD>TClassAdrMap; -TClassAdrMap classAdrMap; - -void __fastcall ClearClassAdrMap(); -// String __fastcall UnmangleName(char* Name); - -TCriticalSection *CrtSection = 0; -TFMain_11011981 *FMain_11011981; - -// --------------------------------------------------------------------------- -__fastcall TFMain_11011981::TFMain_11011981(TComponent* Owner) : dragdropHelper(Handle), TForm(Owner) { - CrtSection = new TCriticalSection; -} - -// --------------------------------------------------------------------------- -__fastcall TFMain_11011981::~TFMain_11011981() { - if (CrtSection) - delete CrtSection; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormClose(TObject *Sender, TCloseAction &Action) { - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - switch (Key) { - case 'G': - GoToAddress(); - break; - case 'N': - NamePosition(); - break; - case 'F': // CTRL + F (1st search on different areas) - { - if (Shift.Contains(ssCtrl)) { - switch (WhereSearch) { - case SEARCH_UNITS: - miSearchUnitClick(Sender); - break; - case SEARCH_UNITITEMS: - miSearchItemClick(Sender); - break; - case SEARCH_RTTIS: - miSearchRTTIClick(Sender); - break; - case SEARCH_FORMS: - miSearchFormClick(Sender); - break; - case SEARCH_CLASSVIEWER: - miSearchVMTClick(Sender); - break; - case SEARCH_STRINGS: - miSearchStringClick(Sender); - break; - case SEARCH_NAMES: - miSearchNameClick(Sender); - break; - // todo rest of locations - } - } - break; - } - case VK_F3: // F3 - (2nd search, continue search with same text) - switch (WhereSearch) { - case SEARCH_UNITS: - FindText(UnitsSearchText); - break; - case SEARCH_UNITITEMS: - FindText(UnitItemsSearchText); - break; - case SEARCH_RTTIS: - FindText(RTTIsSearchText); - break; - case SEARCH_FORMS: - FindText(FormsSearchText); - break; - case SEARCH_CLASSVIEWER: - FindText(VMTsSearchText); - break; - case SEARCH_STRINGS: - FindText(StringsSearchText); - break; - case SEARCH_NAMES: - FindText(NamesSearchText); - break; - } - break; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::Units1Click(TObject *Sender) { - // if (tsUnits->Enabled) - // { - pcInfo->ActivePage = tsUnits; - if (lbUnits->CanFocus()) - ActiveControl = lbUnits; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::RTTI1Click(TObject *Sender) { - // if (tsRTTIs->Enabled) - // { - pcInfo->ActivePage = tsRTTIs; - if (lbRTTIs->CanFocus()) - ActiveControl = lbRTTIs; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::Forms1Click(TObject *Sender) { - // if (tsForms->Enabled) - // { - pcInfo->ActivePage = tsForms; - if (lbForms->CanFocus()) - ActiveControl = lbForms; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::CodeViewer1Click(TObject *Sender) { - // if (tsCodeView->Enabled) - // { - pcWorkArea->ActivePage = tsCodeView; - if (lbCode->CanFocus()) - ActiveControl = lbCode; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ClassViewer1Click(TObject *Sender) { - // if (tsClassView->Enabled) - // { - pcWorkArea->ActivePage = tsClassView; - if (!rgViewerMode->ItemIndex) - if (tvClassesFull->CanFocus()) - ActiveControl = tvClassesFull; - else if (tvClassesShort->CanFocus()) - ActiveControl = tvClassesShort; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::Strings1Click(TObject *Sender) { - // if (tsStrings->Enabled) - // { - pcWorkArea->ActivePage = tsStrings; - if (lbStrings->CanFocus()) - ActiveControl = lbStrings; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::Names1Click(TObject *Sender) { - // if (tsNames->Enabled) - // { - pcWorkArea->ActivePage = tsNames; - if (lbNames->CanFocus()) - ActiveControl = lbNames; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::SourceCode1Click(TObject *Sender) { - // if (tsSourceCode->Enabled) - // { - pcWorkArea->ActivePage = tsSourceCode; - if (lbSourceCode->CanFocus()) - ActiveControl = lbSourceCode; - // } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExitClick(TObject *Sender) { - Close(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::Init() { - IDPFile = ""; - UnitsNum = 0; - CurProcAdr = 0; - CurProcSize = 0; - SelectedAsmItem = ""; - CurUnitAdr = 0; - CodeHistoryPtr = -1; - CodeHistorySize = 0; // HISTORY_CHUNK_LENGTH; - CodeHistory.Length = CodeHistorySize; - CodeHistoryMax = CodeHistoryPtr; - - DelphiVersion = -1; - Caption = "Interactive Delphi Reconstructor by crypto"; - - HInstanceVarAdr = 0xFFFFFFFF; - LastTls = 0; - CtdRegAdr = 0; - - WhereSearch = SEARCH_UNITS; - UnitsSearchFrom = -1; - UnitsSearchText = ""; - - RTTIsSearchFrom = -1; - RTTIsSearchText = ""; - - FormsSearchFrom = -1; - FormsSearchText = ""; - - UnitItemsSearchFrom = -1; - UnitItemsSearchText = ""; - - TreeSearchFrom = 0; - BranchSearchFrom = 0; - VMTsSearchText = ""; - - StringsSearchFrom = 0; - StringsSearchText = ""; - - NamesSearchFrom = 0; - NamesSearchText = ""; - - // Init Menu - miLoadFile->Enabled = true; - miOpenProject->Enabled = true; - miMRF->Enabled = true; - miSaveProject->Enabled = false; - miSaveDelphiProject->Enabled = false; - miExit->Enabled = true; - miMapGenerator->Enabled = false; - miCommentsGenerator->Enabled = false; - miIDCGenerator->Enabled = false; - miLister->Enabled = false; - miClassTreeBuilder->Enabled = false; - miKBTypeInfo->Enabled = false; - miCtdPassword->Enabled = false; - miHex2Double->Enabled = false; - - // Init Units - lbUnits->Clear(); - miRenameUnit->Enabled = false; - miSearchUnit->Enabled = false; - miSortUnits->Enabled = false; - miCopyList->Enabled = false; - // UnitSortField = 0; - miSortUnitsByAdr->Checked = true; - miSortUnitsByOrd->Checked = false; - miSortUnitsByNam->Checked = false; - tsUnits->Enabled = false; - - // Init RTTIs - lbRTTIs->Clear(); - miSearchRTTI->Enabled = false; - miSortRTTI->Enabled = false; - RTTISortField = 0; - miSortRTTIsByAdr->Checked = true; - miSortRTTIsByKnd->Checked = false; - miSortRTTIsByNam->Checked = false; - tsRTTIs->Enabled = false; - - // Init Forms - lbForms->Clear(); - lbAliases->Clear(); - lClassName->Caption = ""; - cbAliases->Clear(); - rgViewFormAs->ItemIndex = 0; - tsForms->Enabled = false; - - // Init Code - lProcName->Caption = ""; - lbCode->Clear(); - lbCode->ScrollWidth = 0; - miGoTo->Enabled = false; - miExploreAdr->Enabled = false; - miName->Enabled = false; - miViewProto->Enabled = false; - miEditFunctionC->Enabled = false; - miXRefs->Enabled = false; - miSwitchFlag->Enabled = false; - bEP->Enabled = false; - bDecompile->Enabled = false; - bCodePrev->Enabled = false; - bCodeNext->Enabled = false; - tsCodeView->Enabled = false; - lbCXrefs->Clear(); - lbCXrefs->Visible = true; - - // Init Strings - lbStrings->Clear(); - miSearchString->Enabled = false; - tsStrings->Enabled = false; - // Init Names - lbNames->Clear(); - tsNames->Enabled = false; - - // Xrefs - lbSXrefs->Clear(); - lbSXrefs->Visible = true; - - // Init Unit Items - lbUnitItems->Clear(); - lbUnitItems->ScrollWidth = 0; - miEditFunctionI->Enabled = false; - miFuzzyScanKB->Enabled = false; - miSearchItem->Enabled = false; - - // Init ClassViewer - ClassTreeDone = false; - tvClassesFull->Items->Clear(); - tvClassesShort->Items->Clear(); - tvClassesShort->BringToFront(); - rgViewerMode->ItemIndex = 1; // Short View - tsClassView->Enabled = false; - - ClearTreeNodeMap(); - ClearClassAdrMap(); - - Update(); - Sleep(0); - - ProjectLoaded = false; - ProjectModified = false; - UserKnowledgeBase = false; - SourceIsLibrary = false; -} - -// --------------------------------------------------------------------------- -PImportNameRec __fastcall TFMain_11011981::GetImportRec(DWORD adr) { - for (int n = 0; n < ImpFuncList->Count; n++) { - PImportNameRec recI = (PImportNameRec)ImpFuncList->Items[n]; - if (adr == recI->address) - return recI; - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FindExports() { - int pos; - - for (int i = 0; i < ExpFuncList->Count; i++) { - PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[i]; - DWORD Adr = recE->address; - if (IsValidImageAdr(Adr) && (pos = Adr2Pos(Adr)) != -1) { - PInfoRec recN = new InfoRec(pos, ikRefine); - recN->SetName(recE->name); - recN->procInfo->flags = 3; // stdcall - Infos[pos] = recN; - SetFlag(cfProcStart | cfExport, pos); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FindImports() { - char *b, *e; - int pos; - String name; - - for (int i = 0; i < TotalSize - 6; i++) { - if (Code[i] == 0xFF && Code[i + 1] == 0x25) { - DWORD adr = *((DWORD*)(Code + i + 2)); - PImportNameRec recI = GetImportRec(adr); - if (recI) { - // name = UnmangleName(recI->name); - if (!Infos[i]) { - PInfoRec recN = new InfoRec(i, ikRefine); - recN->procInfo->procSize = 6; - SetFlag(cfProcStart, i); - SetFlag(cfProcEnd, i + 6); - - if (recI->name.Pos("@Initialization$") || recI->name.Pos("@Finalization$")) { - recN->SetName(recI->module + "." + recI->name); - } - else { - b = strchr(AnsiString(recI->name).c_str() + 1, '@'); - if (b) { - e = strchr(b + 1, '$'); - if (e) { - if (*(e - 1) != '@') - recN->SetName(String(b + 1, e - b - 1)); - else - recN->SetName(String(b + 1, e - b - 2)); - if (recI->name.Pos("$bctr$")) { - recN->ConcatName("@Create"); - recN->kind = ikConstructor; - } - else if (recI->name.Pos("$bdtr$")) { - recN->ConcatName("@Destroy"); - recN->kind = ikDestructor; - } - pos = recN->GetName().Pos("@"); - if (pos > 1) - recN->GetName()[pos] = '.'; - } - } - else - recN->SetName(recI->module + "." + recI->name); - } - for (int n = 0; SysProcs[n].name; n++) { - if (recI->name.Pos(SysProcs[n].name)) { - SysProcs[n].impAdr = Pos2Adr(i); - break; - } - } - SetFlag(cfImport, i); - } - SetFlags(cfCode, i, 6); - } - } - } -} - -// --------------------------------------------------------------------------- -// "Âøèâàåò" VMT â êîä ñ ïîçèöèè pos -void __fastcall TFMain_11011981::StrapVMT(int pos, int ConstId, MConstInfo* ConstInfo) { - if (!ConstInfo) - return; - - // Check dump VMT - BYTE *dump = ConstInfo->Dump; - BYTE *relocs = ConstInfo->Dump + ConstInfo->DumpSz; - bool match = true; - for (int n = 0; n < ConstInfo->DumpSz; n++) { - if (relocs[n] != 0xFF && Code[pos + n] != dump[n]) { - match = false; - break; - } - } - if (!match) - return; - - SetFlags(cfData, pos - 4, ConstInfo->DumpSz + 4); - - int Idx, Pos, VMTOffset = VmtSelfPtr + 4; - // "Strap" fixups - // Get used modules array - WORD *uses = KnowledgeBase.GetModuleUses(ConstInfo->ModuleID); - // Begin fixups data - BYTE *p = ConstInfo->Dump + 2 * (ConstInfo->DumpSz); - FIXUPINFO fixupInfo; - MProcInfo aInfo; - MProcInfo* pInfo = &aInfo; - for (int n = 0; n < ConstInfo->FixupNum; n++) { - fixupInfo.Type = *p; - p++; - fixupInfo.Ofs = *((DWORD*)p); - p += 4; - WORD Len = *((WORD*)p); - p += 2; - fixupInfo.Name = p; - p += Len + 1; - // Name begins with _D - skip it - if (fixupInfo.Name[0] == '_' && fixupInfo.Name[1] == 'D') - continue; - // In VMT all fixups has type 'A' - DWORD Adr = *((DWORD*)(Code + pos + fixupInfo.Ofs)); - - VMTOffset = VmtSelfPtr + 4 + fixupInfo.Ofs; - - if (VMTOffset == VmtIntfTable) { - if (IsValidCodeAdr(Adr) && !Infos[Adr2Pos(Adr)]) { - // Strap IntfTable - Idx = KnowledgeBase.GetProcIdx(ConstInfo->ModuleID, fixupInfo.Name, Code + Adr2Pos(Adr)); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); - } - } - } - } - continue; - } - if (VMTOffset == VmtAutoTable) { - // Strap AutoTable - // Unknown - no examples - continue; - } - if (VMTOffset == VmtInitTable) { - // InitTable ïðåäñòàâëÿåò ñîáîé ññûëêè íà òèïû, êîòîðûå âñòðåòÿòñÿ ïîçæå - continue; - } - if (VMTOffset == VmtTypeInfo) { - // Èíôîðìàöèÿ î òèïå óæå îáðàáîòàíà, ïðîïóñêàåì - continue; - } - if (VMTOffset == VmtFieldTable) { - // Ãðîïóñêàåì, ïîñêîëüêó áóäåì îáðàáàòûâàòü èíôîðìàöèþ î ïîëÿõ ïîçäíåå - continue; - } - if (VMTOffset == VmtMethodTable) { - // Ãðîïóñêàåì, ïîñêîëüêó ìåòîäû áóäóò îáðàáîòàíû ñðåäè ïðî÷èõ ôèêñàïîâ - continue; - } - if (VMTOffset == VmtDynamicTable) { - // Ãðîïóñêàåì, ïîñêîëüêó äèíàìè÷åñêèå âûçîâû áóäóò îáðàáîòàíû ñðåäè ïðî÷èõ ôèêñàïîâ - continue; - } - if (VMTOffset == VmtClassName) { - // ClassName íå îáðàáàòûâàåì - continue; - } - if (VMTOffset == VmtParent) { - // Óêàçûâàåò íà ðîäèòåëüñêèé êëàññ, íå îáðàáàòûâàåì, ïîñêîëüêó îí âñå-ðàâíî âñòðåòèòñÿ îòäåëüíî - continue; - } - if (VMTOffset >= VmtParent + 4 && VMTOffset <= VmtDestroy) { - if (IsValidCodeAdr(Adr) && !Infos[Adr2Pos(Adr)]) { - Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, Code + Adr2Pos(Adr)); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); - } - } - } - // Code not matched, but prototype may be used - else { - PInfoRec recN = new InfoRec(Adr2Pos(Adr), ikRefine); - recN->SetName(fixupInfo.Name); - // Prototype??? - if (uses) { - for (int m = 0; uses[m] != 0xFFFF; m++) { - Idx = KnowledgeBase.GetProcIdx(uses[m], fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (KnowledgeBase.GetProcInfo(Idx, INFO_ARGS, pInfo)) { - switch (pInfo->MethodKind) { - case 'C': - recN->kind = ikConstructor; - break; - case 'D': - recN->kind = ikDestructor; - break; - case 'P': - recN->kind = ikProc; - break; - case 'F': - recN->kind = ikFunc; - recN->type = pInfo->TypeDef; - break; - } - - if (pInfo->Args) { - BYTE callKind = pInfo->CallKind; - recN->procInfo->flags |= callKind; - - ARGINFO argInfo; - BYTE *pp = pInfo->Args; - int ss = 8; - for (int k = 0; k < pInfo->ArgsNum; k++) { - FillArgInfo(k, callKind, &argInfo, &pp, &ss); - recN->procInfo->AddArg(&argInfo); - } - } - // Set kbIdx for fast search - recN->kbIdx = Idx; - recN->procInfo->flags |= PF_KBPROTO; - } - } - } - } - } - } - continue; - } - // Åñëè àäðåñ â êîäîâîì ñåãìåíòå è ñ íèì íå ñâÿçàíî íèêàêîé èíôîðìàöèè - if (IsValidCodeAdr(Adr) && !Infos[Adr2Pos(Adr)]) { - // Ãàçâàíèå òèïà? - if (!IsFlagSet(cfRTTI, Adr2Pos(Adr))) { - // Ãðîöåäóðà? - Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, Code + Adr2Pos(Adr)); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); - } - } - } - // Code not matched, but prototype may be used - else { - PInfoRec recN = new InfoRec(Adr2Pos(Adr), ikRefine); - recN->SetName(fixupInfo.Name); - // Prototype??? - if (uses) { - for (int m = 0; uses[m] != 0xFFFF; m++) { - Idx = KnowledgeBase.GetProcIdx(uses[m], fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (KnowledgeBase.GetProcInfo(Idx, INFO_ARGS, pInfo)) { - switch (pInfo->MethodKind) { - case 'C': - recN->kind = ikConstructor; - break; - case 'D': - recN->kind = ikDestructor; - break; - case 'P': - recN->kind = ikProc; - break; - case 'F': - recN->kind = ikFunc; - recN->type = pInfo->TypeDef; - break; - } - - if (pInfo->Args) { - BYTE callKind = pInfo->CallKind; - recN->procInfo->flags |= callKind; - - ARGINFO argInfo; - BYTE *pp = pInfo->Args; - int ss = 8; - for (int k = 0; k < pInfo->ArgsNum; k++) { - FillArgInfo(k, callKind, &argInfo, &pp, &ss); - recN->procInfo->AddArg(&argInfo); - } - } - // Set kbIdx for fast search - recN->kbIdx = Idx; - recN->procInfo->flags |= PF_KBPROTO; - } - } - } - } - } - } - continue; - } - } - if (uses) - delete[]uses; -} - -// --------------------------------------------------------------------------- -// Check possibility of "straping" procedure (only at the first level) -bool __fastcall TFMain_11011981::StrapCheck(int pos, MProcInfo* ProcInfo) { - int _ap; - String name, fName, _key; - PInfoRec recN; - - if (!ProcInfo) - return false; - - BYTE *dump = ProcInfo->Dump; - // Fixup data begin - BYTE *p = dump + 2 * (ProcInfo->DumpSz); - // If procedure is jmp off_XXXXXXXX, return false - if (*dump == 0xFF && *(dump + 1) == 0x25) - return false; - - FIXUPINFO fixupInfo; - for (int n = 0; n < ProcInfo->FixupNum; n++) { - fixupInfo.Type = *p; - p++; - fixupInfo.Ofs = *((DWORD*)p); - p += 4; - WORD Len = *((WORD*)p); - p += 2; - fixupInfo.Name = p; - p += Len + 1; - - String fName = String(fixupInfo.Name); - // Fixupname begins with "_Dn_" - skip it - if (fName.Pos("_Dn_") == 1) - continue; - // Fixupname begins with "_NF_" - skip it - if (fName.Pos("_NF_") == 1) - continue; - // Fixupname is "_DV_" - skip it - if (SameText(fName, "_DV_")) - continue; - // Fixupname begins with "_DV_" - if (fName.Pos("_DV_") == 1) { - char c = fName[5]; - // Fixupname is _DV_number - skip it - if (c >= '0' && c <= '9') - continue; - // Else transfrom fixupname to normal - if (fName[Len] == '_') - fName = fName.SubString(5, Len - 5); - else - fName = fName.SubString(5, Len - 4); - } - // Empty fixupname - skip it - if (fName == "") - continue; - - DWORD Adr, Ofs, Val = *((DWORD*)(Code + pos + fixupInfo.Ofs)); - if (fixupInfo.Type == 'A' || fixupInfo.Type == 'S') { - Ofs = *((DWORD*)(dump + fixupInfo.Ofs)); - Adr = Val - Ofs; - if (IsValidImageAdr(Adr)) { - _ap = Adr2Pos(Adr); - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) { - // If not import call just compare names - if (_ap >= 0 && !IsFlagSet(cfImport, _ap)) { - if (!recN->SameName(fName)) - return false; - } - // Else may be partial unmatching - else { - name = ExtractProcName(recN->GetName()); - if (!SameText(name, fName) && !SameText(name.SubString(1, name.Length() - 1), fName)) - return false; - } - } - } - } - else if (fixupInfo.Type == 'J') { - Adr = CodeBase + pos + fixupInfo.Ofs + 4 + Val; - if (IsValidCodeAdr(Adr)) { - _ap = Adr2Pos(Adr); - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) { - // If not import call just compare names - if (_ap >= 0 && !IsFlagSet(cfImport, _ap)) { - if (!recN->SameName(fName)) - return false; - } - // Else may be partial unmatching - else { - name = ExtractProcName(recN->GetName()); - if (!SameText(name, fName)) { - String name1 = name.SubString(1, name.Length() - 1); - // Trim last symbol ('A','W') - GetWindowLongW(A) - if (!SameText(fName.SubString(1, name1.Length()), name1)) - return false; - } - } - } - } - } - else if (fixupInfo.Type == 'D') { - Adr = Val; - if (IsValidImageAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) { - if (!recN->SameName(fName)) - return false; - } - } - } - } - return true; -} - -// --------------------------------------------------------------------------- -// "Strap" procedure ProcIdx int code from position pos -void __fastcall TFMain_11011981::StrapProc(int pos, int ProcIdx, MProcInfo* ProcInfo, bool useFixups, int procSize) { - if (!ProcInfo) - return; - // Citadel!!! - if (SameText(ProcInfo->ProcName, "CtdReg")) { - if (procSize == 1) - return; - CtdRegAdr = Pos2Adr(pos); - } - DWORD ProcStart = Pos2Adr(pos); - DWORD ProcEnd = ProcStart + procSize; - // !!! - if (ProcStart == 0x04061A8) - pos = pos; - - String ModuleName = KnowledgeBase.GetModuleName(ProcInfo->ModuleID); - if (!IsUnitExist(ModuleName)) { - // Get unit by pos - PUnitRec recU = GetUnit(Pos2Adr(pos)); - if (recU) { - SetUnitName(recU, ModuleName); - recU->kb = true; - } - } - BYTE* p; - PInfoRec recN; - if (ProcInfo->DumpType == 'D') { - SetFlags(cfData, pos, procSize); - } - else { - SetFlags(cfCode, pos, procSize); - // Mark proc begin - SetFlag(cfProcStart, pos); - // SetFlag(cfProcEnd, pos + procSize - 1); - - recN = GetInfoRec(Pos2Adr(pos)); - if (!recN) - recN = new InfoRec(pos, ikRefine); - // Mark proc end - recN->procInfo->procSize = procSize; - - switch (ProcInfo->MethodKind) { - case 'C': - recN->kind = ikConstructor; - break; - case 'D': - recN->kind = ikDestructor; - break; - case 'F': - recN->kind = ikFunc; - recN->type = ProcInfo->TypeDef; - break; - case 'P': - recN->kind = ikProc; - break; - } - - recN->kbIdx = ProcIdx; - recN->SetName(ProcInfo->ProcName); - // Get Args - if (!recN->MakeArgsManually()) { - BYTE callKind = ProcInfo->CallKind; - recN->procInfo->flags |= callKind; - - int aa = 0, ss = 8; - ARGINFO argInfo; - p = ProcInfo->Args; - if (p) { - for (int k = 0; k < ProcInfo->ArgsNum; k++) { - argInfo.Tag = *p; - p++; - int locflags = *((int*)p); - p += 4; - - if ((locflags & 7) == 1) - argInfo.Tag = 0x23; // Add by ZGL - - argInfo.Register = (locflags & 8); - // Ndx - int ndx = *((int*)p); - p += 4; - - argInfo.Size = 4; - WORD wlen = *((WORD*)p); - p += 2; - argInfo.Name = String((char*)p, wlen); - p += wlen + 1; - wlen = *((WORD*)p); - p += 2; - argInfo.TypeDef = TrimTypeName(String((char*)p, wlen)); - p += wlen + 1; - // Some correction of knowledge base - if (SameText(argInfo.Name, "Message") && SameText(argInfo.TypeDef, "void")) { - argInfo.Name = "Msg"; - argInfo.TypeDef = "TMessage"; - } - - if (SameText(argInfo.TypeDef, "String")) - argInfo.TypeDef = "AnsiString"; - if (SameText(argInfo.TypeDef, "Int64") || SameText(argInfo.TypeDef, "Real") || SameText(argInfo.TypeDef, "Real48") || SameText(argInfo.TypeDef, "Comp") || SameText(argInfo.TypeDef, - "Double") || SameText(argInfo.TypeDef, "Currency") || SameText(argInfo.TypeDef, "TDateTime")) - argInfo.Size = 8; - if (SameText(argInfo.TypeDef, "Extended")) - argInfo.Size = 12; - - if (!callKind) { - if (aa < 3 && argInfo.Size == 4) { - argInfo.Ndx = aa; - aa++; - } - else { - argInfo.Ndx = ss; - ss += argInfo.Size; - } - } - else { - argInfo.Ndx = ss; - ss += argInfo.Size; - } - recN->procInfo->AddArg(&argInfo); - } - } - } - recN->procInfo->flags |= PF_KBPROTO; - } - // Fix used procedure - KnowledgeBase.SetUsedProc(ProcIdx); - - if (useFixups && ProcInfo->FixupNum) { - // Get array of used modules - int Idx, size; - WORD *uses = KnowledgeBase.GetModuleUses(ProcInfo->ModuleID); - // Ãà÷àëî äàííûõ ïî ôèêñàïàì - p = ProcInfo->Dump + 2 * ProcInfo->DumpSz; - FIXUPINFO fixupInfo; - - MConstInfo acInfo; - MConstInfo *cInfo = &acInfo; - MTypeInfo atInfo; - MTypeInfo *tInfo = &atInfo; - MVarInfo avInfo; - MVarInfo *vInfo = &avInfo; - MResStrInfo arsInfo; - MResStrInfo *rsInfo = &arsInfo; - MProcInfo aInfo; - MProcInfo* pInfo = &aInfo; - DWORD Adr, Adr1, Ofs, Val; - WORD Len; - String fName; - - for (int n = 0; n < ProcInfo->FixupNum; n++) { - fixupInfo.Type = *p; - p++; - fixupInfo.Ofs = *((DWORD*)p); - p += 4; - Len = *((WORD*)p); - p += 2; - fixupInfo.Name = p; - p += Len + 1; - fName = String(fixupInfo.Name, Len); - // Fixupname begins with _Dn_ - skip it - if (fName.Pos("_Dn_") == 1) - continue; - // Fixupname begins with _NF_ - skip it - if (fName.Pos("_NF_") == 1) - continue; - // Fixupname is "_DV_" - skip it - if (SameText(fName, "_DV_")) - continue; - // Fixupname begins with _DV_ - if (fName.Pos("_DV_") == 1) { - char c = fName[5]; - // Fixupname is _DV_number - skip it - if (c >= '0' && c <= '9') - continue; - // Else transfrom fixupname to normal - if (fName[Len] == '_') - fName = fName.SubString(5, Len - 5); - else - fName = fName.SubString(5, Len - 4); - } - if (fName == "" || fName == ".") - continue; - - Val = *((DWORD*)(Code + pos + fixupInfo.Ofs)); - // FixupName is the same as ProcName - if (SameText(fName, ProcInfo->ProcName)) { - // !!! - // Need to use this information: - // CaseStudio, 405ae4 - call [offs+4*eax] - how to use offs? And offs has cfLoc - // Val inside procedure - possible jump address for switch (or call) - if (fixupInfo.Type == 'J') { - Adr = CodeBase + pos + fixupInfo.Ofs + Val + 4; - if (Adr >= ProcStart && Adr < ProcEnd) - SetFlag(cfLoc | cfEmbedded, Adr2Pos(Adr)); - } - continue; - } - // Ñíà÷àëà ïîäñ÷èòàåì àäðåñ, à ïîòîì áóäåì ïûòàòüñÿ îïðåäåëÿòü ñåêöèþ - if (fixupInfo.Type == 'A' || fixupInfo.Type == 'S' || fixupInfo.Type == '4' || fixupInfo.Type == '8') { - // Ñìîòðèì, êàêàÿ âåëè÷èíà ñòîèò â äàìïå â ïîçèöèè ôèêñàïà - Ofs = *((DWORD*)(ProcInfo->Dump + fixupInfo.Ofs)); - Adr = Val - Ofs; - } - else if (fixupInfo.Type == 'J') { - Adr = CodeBase + pos + fixupInfo.Ofs + Val + 4; - } - else if (fixupInfo.Type == 'D' || fixupInfo.Type == '6' || fixupInfo.Type == '5') { - Adr = Val; - } - else { - ShowMessage("Unknown fixup type:" + String(fixupInfo.Type)); - } - - bool isHInstance = (stricmp(fixupInfo.Name, "HInstance") == 0); - if (!IsValidImageAdr(Adr)) { - // Ãîêà çäåñü íàáëþäàëèñü ëèøü îäíè ThreadVars è TlsLast - if (!stricmp(fixupInfo.Name, "TlsLast")) { - LastTls = Val; - } - else { - recN = GetInfoRec(Pos2Adr(pos + fixupInfo.Ofs)); - if (!recN) { - recN = new InfoRec(pos + fixupInfo.Ofs, ikData); - recN->SetName(fixupInfo.Name); - // Îïðåäåëèì òèï Var - Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.VarOffsets[Idx].NamId; - if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) { - if (vInfo->Type == 'T') - recN->kind = ikThreadVar; - recN->kbIdx = Idx; - recN->type = TrimTypeName(vInfo->TypeDef); - } - } - } - } - continue; - } - - if (Adr >= ProcStart && Adr < ProcEnd) - continue; - - if (isHInstance) { - Adr1 = *((DWORD*)(Code + Adr2Pos(Adr))); - if (IsValidImageAdr(Adr1)) - HInstanceVarAdr = Adr1; - else - HInstanceVarAdr = Adr; - } - - int Sections = KnowledgeBase.GetItemSection(uses, fixupInfo.Name); - // Àäðåñ â êîäîâîì ñåãìåíòå âíå òåëà ñàìîé ôóíêöèè - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - if (!recN) { - switch (Sections) { - case KB_CONST_SECTION: - Idx = KnowledgeBase.GetConstIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ConstOffsets[Idx].NamId; - // Åñëè èìÿ íà÷èíàåòñÿ íà _DV_, çíà÷èò ýòî VMT - if (!memcmp(fixupInfo.Name, "_DV_", 4)) { - if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) - StrapVMT(Adr2Pos(Adr) + 4, Idx, cInfo); - } - else { - } - } - break; - case KB_TYPE_SECTION: - Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.TypeOffsets[Idx].NamId; - if (KnowledgeBase.GetTypeInfo(Idx, 0, tInfo)) { - recN = new InfoRec(Adr2Pos(Adr), ikData); - recN->kbIdx = Idx; - recN->SetName(tInfo->TypeName); - } - } - break; - case KB_VAR_SECTION: - Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.VarOffsets[Idx].NamId; - if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) { - recN = new InfoRec(Adr2Pos(Adr), ikData); - recN->kbIdx = Idx; - recN->SetName(vInfo->VarName); - recN->type = TrimTypeName(vInfo->TypeDef); - } - } - break; - case KB_RESSTR_SECTION: - Idx = KnowledgeBase.GetResStrIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ResStrOffsets[Idx].NamId; - if (KnowledgeBase.GetResStrInfo(Idx, 0, rsInfo)) { - recN = new InfoRec(Adr2Pos(Adr), ikData); - recN->kbIdx = Idx; - recN->SetName(rsInfo->ResStrName); - recN->type = rsInfo->TypeDef; - } - } - break; - case KB_PROC_SECTION: - Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, Code + Adr2Pos(Adr)); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) - StrapProc(Adr2Pos(Adr), Idx, pInfo, true, pInfo->DumpSz); - } - } - else { - Idx = KnowledgeBase.GetProcIdx(uses, fixupInfo.Name, 0); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - if (!SameText(fName, "@Halt")) { - StrapProc(Adr2Pos(Adr), Idx, pInfo, false, EstimateProcSize(Adr)); - } - else { - DISINFO _disInfo; - int _bytes = EstimateProcSize(Adr); - while (_bytes > 0) { - int _instrlen = Disasm.Disassemble(Code + Adr2Pos(Adr), (__int64)Adr, &_disInfo, 0); - if (_disInfo.Branch && !_disInfo.Conditional) { - Adr = _disInfo.Immediate; - Idx = KnowledgeBase.GetProcIdx(uses, "@Halt0", 0); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) - StrapProc(Adr2Pos(Adr), Idx, pInfo, false, EstimateProcSize(Adr)); - } - } - break; - } - _bytes -= _instrlen; - } - } - } - } - } - - } - break; - } - continue; - } - } - // Àäðåñ â ñåêöèè DATA - if (IsValidImageAdr(Adr)) { - int _pos = Adr2Pos(Adr); - if (_pos >= 0) { - recN = GetInfoRec(Adr); - if (!recN) { - switch (Sections) { - case KB_CONST_SECTION: - Idx = KnowledgeBase.GetConstIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ConstOffsets[Idx].NamId; - if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) { - String cname = ""; - if (cInfo->ConstName.Pos("_DV_") == 1) { - char c = cInfo->ConstName[5]; - if (c > '9') { - if (cInfo->ConstName[Len] == '_') - cname = cInfo->ConstName.SubString(5, Len - 5); - else - cname = cInfo->ConstName.SubString(5, Len - 4); - } - } - else - cname = cInfo->ConstName; - - recN = new InfoRec(_pos, ikData); - recN->kbIdx = Idx; - recN->SetName(cname); - recN->type = cInfo->TypeDef; - } - } - break; - case KB_TYPE_SECTION: - Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.TypeOffsets[Idx].NamId; - if (KnowledgeBase.GetTypeInfo(Idx, 0, tInfo)) { - recN = new InfoRec(_pos, ikData); - recN->kbIdx = Idx; - recN->SetName(tInfo->TypeName); - } - } - break; - case KB_VAR_SECTION: - Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.VarOffsets[Idx].NamId; - if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) { - recN = new InfoRec(_pos, ikData); - recN->kbIdx = Idx; - recN->SetName(vInfo->VarName); - recN->type = TrimTypeName(vInfo->TypeDef); - } - } - break; - case KB_RESSTR_SECTION: - Idx = KnowledgeBase.GetResStrIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ResStrOffsets[Idx].NamId; - if (KnowledgeBase.GetResStrInfo(Idx, 0, rsInfo)) { - recN = new InfoRec(_pos, ikData); - recN->kbIdx = Idx; - recN->SetName(rsInfo->ResStrName); - recN->type = rsInfo->TypeDef; - } - } - break; - } - } - } - else { - switch (Sections) { - case KB_CONST_SECTION: - Idx = KnowledgeBase.GetConstIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ConstOffsets[Idx].NamId; - if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) { - String cname = ""; - if (cInfo->ConstName.Pos("_DV_") == 1) { - char c = cInfo->ConstName[5]; - if (c > '9') { - if (cInfo->ConstName[Len] == '_') - cname = cInfo->ConstName.SubString(5, Len - 5); - else - cname = cInfo->ConstName.SubString(5, Len - 4); - } - } - else - cname = cInfo->ConstName; - - AddToBSSInfos(Adr, cname, cInfo->TypeDef); - } - } - break; - case KB_TYPE_SECTION: - Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.TypeOffsets[Idx].NamId; - if (KnowledgeBase.GetTypeInfo(Idx, 0, tInfo)) { - AddToBSSInfos(Adr, tInfo->TypeName, ""); - } - } - break; - case KB_VAR_SECTION: - Idx = KnowledgeBase.GetVarIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.VarOffsets[Idx].NamId; - if (KnowledgeBase.GetVarInfo(Idx, 0, vInfo)) { - AddToBSSInfos(Adr, vInfo->VarName, TrimTypeName(vInfo->TypeDef)); - } - } - break; - case KB_RESSTR_SECTION: - Idx = KnowledgeBase.GetResStrIdx(uses, fixupInfo.Name); - if (Idx != -1) { - Idx = KnowledgeBase.ResStrOffsets[Idx].NamId; - if (KnowledgeBase.GetResStrInfo(Idx, 0, rsInfo)) { - AddToBSSInfos(Adr, rsInfo->ResStrName, rsInfo->TypeDef); - } - } - break; - } - } - } - } - if (uses) - delete[]uses; - } -} -// --------------------------------------------------------------------------- -int DelphiVersions[] = {2, 3, 4, 5, 6, 7, 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014, 0}; - -int __fastcall TFMain_11011981::GetDelphiVersion() { - WORD moduleID; - int idx, num, pos, version; - DWORD unitsTab, iniAdr, finAdr, vmtAdr, adr; - DWORD TControlInstSize; - PInfoRec recN; - String name, KBFileName; - MKnowledgeBase SysKB; - MProcInfo aInfo; - MProcInfo* pInfo = &aInfo; - - if (IsExtendedInitTab(&unitsTab)) // >=2010 - { - KBFileName = BinsDir + "syskb2014.bin"; - if (SysKB.Open(AnsiString(KBFileName).c_str())) { - moduleID = SysKB.GetModuleID("System"); - if (moduleID != 0xFFFF) { - // Find index of function "StringCopy" in this module - idx = SysKB.GetProcIdx(moduleID, "StringCopy"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return 2014; - } - } - } - SysKB.Close(); - } - KBFileName = BinsDir + "syskb2013.bin"; - if (SysKB.Open(AnsiString(KBFileName).c_str())) { - moduleID = SysKB.GetModuleID("System"); - if (moduleID != 0xFFFF) { - // Find index of function "@FinalizeResStrings" in this module - idx = SysKB.GetProcIdx(moduleID, "@FinalizeResStrings"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return 2013; - } - } - } - SysKB.Close(); - } - - KBFileName = BinsDir + "syskb2012.bin"; - if (SysKB.Open(AnsiString(KBFileName).c_str())) { - moduleID = SysKB.GetModuleID("System"); - if (moduleID != 0xFFFF) { - // Find index of function "@InitializeControlWord" in this module - idx = SysKB.GetProcIdx(moduleID, "@InitializeControlWord"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return 2012; - } - } - } - SysKB.Close(); - } - - KBFileName = BinsDir + "syskb2011.bin"; - if (SysKB.Open(AnsiString(KBFileName).c_str())) { - moduleID = SysKB.GetModuleID("System"); - if (moduleID != 0xFFFF) { - // Find index of function "ErrorAt" in this module - idx = SysKB.GetProcIdx(moduleID, "ErrorAt"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return 2011; - } - } - } - SysKB.Close(); - } - return 2010; - } - - TControlInstSize = 0; - // Ãðîáóåì äëÿ íà÷àëà êàê â DeDe (Èùåì òèï TControl) - for (int n = 0; n < TotalSize - 14; n += 4) { - if (Image[n] == 7 && Image[n + 1] == 8 && Image[n + 2] == 'T' && Image[n + 3] == 'C' && Image[n + 4] == 'o' && Image[n + 5] == 'n' && Image[n + 6] == 't' && Image[n + 7] == 'r' && Image[n + - 8] == 'o' && Image[n + 9] == 'l') { - // Ãîñëå òèïà äîëæåí ñëåäîâàòü óêàçàòåëü íà òàáëèöó VMT (0) - vmtAdr = *((DWORD*)(Image + n + 10)); - if (IsValidImageAdr(vmtAdr)) { - // Ãðîâåðÿåì ñìåùåíèå -0x18 - TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x18)); - if (TControlInstSize == 0xA8) - return 2; - // Ãðîâåðÿåì ñìåùåíèå -0x1C - TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x1C)); - if (TControlInstSize == 0xB0 || TControlInstSize == 0xB4) - return 3; - // Ãðîâåðÿåì ñìåùåíèå -0x28 - TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x28)); - if (TControlInstSize == 0x114) - return 4; - if (TControlInstSize == 0x120) - return 5; - if (TControlInstSize == 0x15C) // 6 èëè 7 - { - DWORD TFormInstSize = 0; - // Èùåì òèï TForm (âûáîð ìåæäó âåðñèåé 6 è 7) - for (int m = 0; m < TotalSize - 11; m += 4) { - if (Image[m] == 7 && Image[m + 1] == 5 && Image[m + 2] == 'T' && Image[m + 3] == 'F' && Image[m + 4] == 'o' && Image[m + 5] == 'r' && Image[m + 6] == 'm') { - // Ãîñëå òèïà äîëæåí ñëåäîâàòü óêàçàòåëü íà òàáëèöó VMT (0) - vmtAdr = *((DWORD*)(Image + m + 7)); - if (IsValidImageAdr(vmtAdr)) { - // Ãðîâåðÿåì ñìåùåíèå -0x28 - TFormInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x28)); - if (TFormInstSize == 0x2F0) - return 6; - if (TFormInstSize == 0x2F8) - return 7; - } - } - } - break; - } - if (TControlInstSize == 0x164) - return 2005; - if (TControlInstSize == 0x190) - break; // 2006 èëè 2007 - // Ãðîâåðÿåì ñìåùåíèå -0x34 - TControlInstSize = *((DWORD*)(Image + Adr2Pos(vmtAdr) - 0x34)); - if (TControlInstSize == 0x1A4) - return 2009; - // if (TControlInstSize == 0x1AC) return 2010; - } - } - } - // Îñòàâøèåñÿ âàðèàíòû ïðîâåðÿåì ÷åðåç áàçó çíàíèé - for (int v = 0; DelphiVersions[v]; v++) { - version = DelphiVersions[v]; - if (TControlInstSize == 0x190 && version != 2006 && version != 2007) - continue; - KBFileName = BinsDir + "syskb" + version + ".bin"; - if (SysKB.Open(AnsiString(KBFileName).c_str())) { - moduleID = SysKB.GetModuleID("System"); - if (moduleID != 0xFFFF) { - // Èùåì èíäåêñ ôóíêöèè "System" â äàííîì ìîäóëå - idx = SysKB.GetProcIdx(moduleID, "System"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - if (version == 4 || version == 5) { - idx = SysKB.GetProcIdx(moduleID, "@HandleAnyException"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return version; - } - } - } - else if (version == 2006 || version == 2007) { - idx = SysKB.GetProcIdx(moduleID, "GetObjectClass"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return version; - } - } - } - else if (version == 2009 || version == 2010) { - // Èùåì èíäåêñ ôóíêöèè "@Halt0" â äàííîì ìîäóëå - idx = SysKB.GetProcIdx(moduleID, "@Halt0"); - if (idx != -1) { - pInfo = SysKB.GetProcInfo(SysKB.ProcOffsets[idx].NamId, INFO_DUMP, &aInfo); - pos = SysKB.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - SysKB.Close(); - return version; - } - } - } - else { - SysKB.Close(); - return version; - } - } - } - } - SysKB.Close(); - } - } - // Analyze VMTs (if exists) - version = -1; - for (int n = 0; n < CodeSize; n += 4) { - vmtAdr = *((DWORD*)(Code + n)); // Points to vmt0 (VmtSelfPtr) - // VmtSelfPtr - if (IsValidCodeAdr(vmtAdr)) { - if (Pos2Adr(n) == vmtAdr - 0x34) { - // VmtInitTable - adr = *((DWORD*)(Code + n + 4)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtTypeInfo - adr = *((DWORD*)(Code + n + 8)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtFieldTable - adr = *((DWORD*)(Code + n + 12)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtMethodTable - adr = *((DWORD*)(Code + n + 16)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtDynamicTable - adr = *((DWORD*)(Code + n + 20)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtClassName - adr = *((DWORD*)(Code + n + 24)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtInstanceSize - adr = *((DWORD*)(Code + n + 28)); - if (!adr || IsValidCodeAdr(adr)) - continue; - version = Pos2Adr(n) - vmtAdr; - break; - } - else if (Pos2Adr(n) == vmtAdr - 0x40 || Pos2Adr(n) == vmtAdr - 0x4C || Pos2Adr(n) == vmtAdr - 0x58) { - // VmtIntfTable - adr = *((DWORD*)(Code + n + 4)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtAutoTable - adr = *((DWORD*)(Code + n + 8)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtInitTable - adr = *((DWORD*)(Code + n + 12)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtTypeInfo - adr = *((DWORD*)(Code + n + 16)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtFieldTable - adr = *((DWORD*)(Code + n + 20)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtMethodTable - adr = *((DWORD*)(Code + n + 24)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtDynamicTable - adr = *((DWORD*)(Code + n + 28)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtClassName - adr = *((DWORD*)(Code + n + 32)); - if (adr && !IsValidCodeAdr(adr)) - continue; - // VmtInstanceSize - adr = *((DWORD*)(Code + n + 36)); - if (!adr || IsValidCodeAdr(adr)) - continue; - version = Pos2Adr(n) - vmtAdr; - break; - } - } - } - if (version == -0x34) - return 2; - if (version == -0x40) - return 3; - if (version == -0x58) - return 2009; - /* - //Check that system is in external rtl - num = *((DWORD*)(Code + unitsTab - 8)); - for (int n = 0; n < num; n++, unitsTab += 8) - { - iniAdr = *((DWORD*)(Code + unitsTab)); - if (iniAdr && IsValidImageAdr(iniAdr) && IsFlagSet(cfImport, Adr2Pos(iniAdr))) - { - recN = GetInfoRec(iniAdr); - pos = recN->name.Pos("."); - if (pos && SameText(recN->name.SubString(pos + 1, 22), "@System@Initialization")) - { - name = recN->name.SubString(1, pos - 1); - if (SameText(name, "rtl120")) return 2009; - } - } - finAdr = *((DWORD*)(Code + unitsTab + 4)); - if (finAdr && IsValidImageAdr(finAdr) && IsFlagSet(cfImport, Adr2Pos(finAdr)))) - { - recN = GetInfoRec(finAdr); - pos = recN->name.Pos("."); - if (pos) - { - name = recN->name.SubString(1, pos - 1); - } - } - } - */ - // as - // try to find the Delphi version based on imported delphi bpls.... (if any) - typedef struct { - char* versionVcl; // digital part of version present in vclXXX file name - char* versionRtl; // digital part of version present in rtlXXX file name - char* versionString; // full string of vcl/rtl bpl from file properties - int versionForIdr; // value that returns to caller - } DelphiBplVersionRec; - - const DelphiBplVersionRec delphiBplVer[] = { // Borland - {"vcl30.dpl", "", "3.0.5.53", 3}, // no rtl30.dpl! - {"vcl40.bpl", "", "4.0.5.38", 4}, // no rtl40.bpl! - {"vcl60.bpl", "rtl60.bpl", "6.0.6.240", 6}, {"vcl60.bpl", "rtl60.bpl", "6.0.6.243", 6}, {"vcl70.bpl", "rtl70.bpl", "7.0.4.453", 7}, {"vcl90.bpl", "rtl90.bpl", "9.0.1761.24408", 2005}, - {"vcl100.bpl", "rtl100.bpl", "10.0.2151.25345", 2006}, // SP2 - {"vcl100.bpl", "rtl100.bpl", "11.0.2627.5503", 2007}, // CodeGear - {"vcl100.bpl", "rtl100.bpl", "11.0.2902.10471", 2007}, {"vcl120.bpl", "rtl120.bpl", "12.0.3210.17555", 2009}, // Embarcadero - {"", "", "", 0}}; - - String rtlBplName, vclBplName, rtlBpl, vclBpl; - - for (int n = 0; n < ImpModuleList->Count; n++) { - if (ImpModuleList->Strings[n].SubString(1, 3).LowerCase() == "rtl") - rtlBpl = ImpModuleList->Strings[n].LowerCase(); - else if (ImpModuleList->Strings[n].SubString(1, 3).LowerCase() == "vcl") - vclBpl = ImpModuleList->Strings[n].LowerCase(); - - if (rtlBpl != "" && vclBpl != "") - break; - } - - // or (||) is here because Delphi3 and 4 do not have rtl... - if (rtlBpl != "" || vclBpl != "") { - for (int i = 0; delphiBplVer[i].versionForIdr; ++i) { - rtlBplName = String(delphiBplVer[i].versionRtl); - vclBplName = String(delphiBplVer[i].versionVcl); - - if (vclBplName != vclBpl) - continue; - - // if we found something - lets continue the analysis - // here we have two cases - // (i) bpl are near the input Delphi target or - // (ii) it was installed into system dir...(or any dir in %PATH% !) - - String srcPath = ExtractFilePath(SourceFile); - String rtlFile = !rtlBplName.IsEmpty() ? srcPath + rtlBplName : rtlBplName; - String vclFile = srcPath + vclBplName; - - if (!FileExists(vclFile)) { - // we'll not look into windows\\system32 only... - // instead we leave path as no path -> system will scan for us - // in all the %PATH% directories (when doing LoadLibrary)! - rtlFile = rtlBplName; - vclFile = vclBplName; - } - - // check the export of bpl - it must have 2 predefined functions - if (!((rtlFile == "" || IsBplByExport(AnsiString(rtlFile).c_str())) && IsBplByExport(AnsiString(vclFile).c_str()))) { - ShowMessage("Input file imports Delphi system packages (" + rtlFile + ", " + vclFile + ")." "\r\nIn order to figure out the version, please put it nearby"); - break; - } - - String rtlBplVersion = GetModuleVersion(rtlFile); - String vclBplVersion = GetModuleVersion(vclFile); - // hack for D3 and 4 - if (rtlBplVersion == "") - rtlBplVersion = vclBplVersion; - if (rtlBplVersion == vclBplVersion && rtlBplVersion == String(delphiBplVer[i].versionString)) - return delphiBplVer[i].versionForIdr; - } - } - if (version == -0x4C) - return 1; - // here we failed to find the version.....sorry - return -1; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::InitSysProcs() { - int Idx, pos; - MProcInfo aInfo, *pInfo; - - SysProcsNum = 0; - WORD moduleID = KnowledgeBase.GetModuleID("System"); - for (int n = 0; SysProcs[n].name; n++) { - Idx = KnowledgeBase.GetProcIdx(moduleID, SysProcs[n].name); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, &aInfo); - if (SysProcs[n].impAdr) { - StrapProc(Adr2Pos(SysProcs[n].impAdr), Idx, pInfo, false, 6); - } - else { - pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - PInfoRec recN = new InfoRec(pos, ikRefine); - recN->SetName(SysProcs[n].name); - StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); - } - } - } - } - SysProcsNum++; - } - moduleID = KnowledgeBase.GetModuleID("SysInit"); - for (int n = 0; SysInitProcs[n].name; n++) { - Idx = KnowledgeBase.GetProcIdx(moduleID, SysInitProcs[n].name); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, &aInfo); - if (SysInitProcs[n].impAdr) { - StrapProc(Adr2Pos(SysInitProcs[n].impAdr), Idx, pInfo, false, 6); - } - pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); - if (pos != -1) { - PInfoRec recN = new InfoRec(pos, ikRefine); - recN->SetName(SysInitProcs[n].name); - StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); - if (n == 1) - SourceIsLibrary = true; - } - } - } - SysProcsNum++; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::SetVmtConsts(int version) { - switch (version) { - case 2: - VmtSelfPtr = -0x34; // ??? (=0???) - VmtInitTable = -0x30; - VmtTypeInfo = -0x2C; - VmtFieldTable = -0x28; - VmtMethodTable = -0x24; - VmtDynamicTable = -0x20; - VmtClassName = -0x1C; - VmtInstanceSize = -0x18; - VmtParent = -0x14; - VmtDefaultHandler = -0x10; - VmtNewInstance = -0xC; - VmtFreeInstance = -8; - VmtDestroy = -4; - break; - case 3: - VmtSelfPtr = -0x40; - VmtIntfTable = -0x3C; - VmtAutoTable = -0x38; - VmtInitTable = -0x34; - VmtTypeInfo = -0x30; - VmtFieldTable = -0x2C; - VmtMethodTable = -0x28; - VmtDynamicTable = -0x24; - VmtClassName = -0x20; - VmtInstanceSize = -0x1C; - VmtParent = -0x18; - VmtSafeCallException = -0x14; - VmtDefaultHandler = -0x10; - VmtNewInstance = -0xC; - VmtFreeInstance = -8; - VmtDestroy = -4; - break; - case 4: - case 5: - case 6: - case 7: - case 2005: - case 2006: - case 2007: - VmtSelfPtr = -0x4C; - VmtIntfTable = -0x48; - VmtAutoTable = -0x44; - VmtInitTable = -0x40; - VmtTypeInfo = -0x3C; - VmtFieldTable = -0x38; - VmtMethodTable = -0x34; - VmtDynamicTable = -0x30; - VmtClassName = -0x2C; - VmtInstanceSize = -0x28; - VmtParent = -0x24; - VmtSafeCallException = -0x20; - VmtAfterConstruction = -0x1C; - VmtBeforeDestruction = -0x18; - VmtDispatch = -0x14; - VmtDefaultHandler = -0x10; - VmtNewInstance = -0xC; - VmtFreeInstance = -8; - VmtDestroy = -4; - break; - case 2009: - case 2010: - VmtSelfPtr = -0x58; - VmtIntfTable = -0x54; - VmtAutoTable = -0x50; - VmtInitTable = -0x4C; - VmtTypeInfo = -0x48; - VmtFieldTable = -0x44; - VmtMethodTable = -0x40; - VmtDynamicTable = -0x3C; - VmtClassName = -0x38; - VmtInstanceSize = -0x34; - VmtParent = -0x30; - VmtEquals = -0x2C; - VmtGetHashCode = -0x28; - VmtToString = -0x24; - VmtSafeCallException = -0x20; - VmtAfterConstruction = -0x1C; - VmtBeforeDestruction = -0x18; - VmtDispatch = -0x14; - VmtDefaultHandler = -0x10; - VmtNewInstance = -0xC; - VmtFreeInstance = -8; - VmtDestroy = -4; - break; - case 2011: - case 2012: - case 2013: - case 2014: - VmtSelfPtr = -0x58; - VmtIntfTable = -0x54; - VmtAutoTable = -0x50; - VmtInitTable = -0x4C; - VmtTypeInfo = -0x48; - VmtFieldTable = -0x44; - VmtMethodTable = -0x40; - VmtDynamicTable = -0x3C; - VmtClassName = -0x38; - VmtInstanceSize = -0x34; - VmtParent = -0x30; - VmtEquals = -0x2C; - VmtGetHashCode = -0x28; - VmtToString = -0x24; - VmtSafeCallException = -0x20; - VmtAfterConstruction = -0x1C; - VmtBeforeDestruction = -0x18; - VmtDispatch = -0x14; - VmtDefaultHandler = -0x10; - VmtNewInstance = -0xC; - VmtFreeInstance = -8; - VmtDestroy = -4; - // VmtQueryInterface = 0; - // VmtAddRef = 4; - // VmtRelease = 8; - // VmtCreateObject = 0xC; - break; - } -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::IsUnitExist(String Name) { - for (int n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - if (recU->names->IndexOf(Name) != -1) - return true; - } - return false; -} - -// --------------------------------------------------------------------------- -PUnitRec __fastcall TFMain_11011981::GetUnit(DWORD Adr) { - PUnitRec _res; - - CrtSection->Enter(); - _res = 0; - for (int n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - if (Adr >= recU->fromAdr && Adr < recU->toAdr) - _res = recU; - } - CrtSection->Leave(); - return _res; -} - -// --------------------------------------------------------------------------- -String __fastcall TFMain_11011981::GetUnitName(PUnitRec recU) { - if (recU) { - if (recU->names->Count == 1) - return recU->names->Strings[0]; - else - return "_Unit" + String(recU->iniOrder); - } - return ""; -} - -// --------------------------------------------------------------------------- -String __fastcall TFMain_11011981::GetUnitName(DWORD Adr) { - int n; - String Result = ""; - - PUnitRec recU = GetUnit(Adr); - if (recU) { - for (n = 0; n < recU->names->Count; n++) { - if (n) - Result += ", "; - Result += recU->names->Strings[n]; - } - } - return Result; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::SetUnitName(PUnitRec recU, String name) { - if (recU && recU->names->IndexOf(name) == -1) - recU->names->Add(name); -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::InOneUnit(DWORD Adr1, DWORD Adr2) { - for (int n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - if (Adr1 >= recU->fromAdr && Adr1 < recU->toAdr && Adr2 >= recU->fromAdr && Adr2 < recU->toAdr) - return true; - } - return false; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::GetSegmentNo(DWORD Adr) { - for (int n = 0; n < SegmentList->Count; n++) { - PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; - if (segInfo->Start <= Adr && Adr < segInfo->Start + segInfo->Size) - return n; - } - return -1; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall FollowInstructions(DWORD fromAdr, DWORD toAdr) { - int instrLen; - int fromPos = Adr2Pos(fromAdr); - int curPos = fromPos; - DWORD curAdr = fromAdr; - DISINFO DisInfo; - - while (1) { - if (curAdr >= toAdr) - break; - if (IsFlagSet(cfInstruction, curPos)) - break; - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - if (!instrLen) - break; - SetFlag(cfInstruction, curPos); - } - return curAdr; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::EstimateProcSize(DWORD fromAdr) { - BYTE op; - int row, num, instrLen, instrLen1, instrLen2, Pos; - int fromPos = Adr2Pos(fromAdr); - int curPos = fromPos; - DWORD curAdr = fromAdr; - DWORD lastAdr = 0; - DWORD Adr, Adr1, lastMovAdr = 0; - PInfoRec recN; - DISINFO DisInfo; - - int outRows = MAX_DISASSEMBLE; - if (IsFlagSet(cfImport, fromPos)) - outRows = 1; - - for (row = 0; row < outRows; row++) { - // Exception table - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - curPos += 4 + 8 * num; - curAdr += 4 + 8 * num; - continue; - } - - BYTE b1 = Code[curPos]; - BYTE b2 = Code[curPos + 1]; - if (!b1 && !b2 && !lastAdr) - break; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) break; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - // Code - SetFlags(cfCode, curPos, instrLen); - // Instruction begin - SetFlag(cfInstruction, curPos); - - op = Disasm.GetOp(DisInfo.Mnem); - - if (curAdr >= lastAdr) - lastAdr = 0; - - if (op == OP_JMP) { - if (curAdr == fromAdr) { - curAdr += instrLen; - break; - } - if (DisInfo.OpType[0] == otMEM) { - if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) { - curAdr += instrLen; - break; - } - } - if (DisInfo.OpType[0] == otIMM) { - Adr = DisInfo.Immediate; - if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) { - curAdr += instrLen; - break; - } - if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) { - curAdr += instrLen; - break; - } - if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) { - curAdr += instrLen; - break; - } - } - } - // End of procedure - if (DisInfo.Ret) // && (!lastAdr || curAdr == lastAdr)) - { - if (!IsFlagSet(cfLoc, Pos + instrLen)) { - curAdr += instrLen; - break; - } - } - - if (op == OP_MOV) - lastMovAdr = DisInfo.Offset; - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) - // near absolute indirect jmp (Case) - { - if (!IsValidCodeAdr(DisInfo.Offset)) { - curAdr += instrLen; - break; - } - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Àäðåñ òàáëèöû - ïîñëåäíèå 4 áàéòà èíñòðóêöèè - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Àíàëèçèðóåì ïðîìåæóòîê íà ïðåäìåò òàáëèöû cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // Åñëè åñòü cTblAdr, ïðîïóñêàåì ýòó òàáëèöó - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - Pos += CNum; - Adr += CNum; - } - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidImageAdr(Adr1) || Adr1 < fromAdr) - break; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - // if (!instrLen1) return Size; - - recN = GetInfoRec(DisInfo.Immediate); - if (recN) { - if (recN->SameName("@HandleFinally")) { - // jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - /* - //@2 - Adr1 = DisInfo.Immediate - 4; - Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); - if (Adr > lastAdr) lastAdr = Adr; - */ - } - else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // Set cfETable to output data correctly - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Pos += 4; - // dd offset ExceptionProc - Pos += 4; - } - } - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - if (b1 == 0xEB || // short relative abs jmp or cond jmp - (b1 >= 0x70 && b1 <= 0x7F) || (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) { - Adr = DisInfo.Immediate; - if (IsValidImageAdr(Adr)) { - SetFlag(cfLoc, Adr2Pos(Adr)); - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (b1 == 0xE9) // relative abs jmp or cond jmp - { - Adr = DisInfo.Immediate; - if (IsValidImageAdr(Adr)) { - SetFlag(cfLoc, Adr2Pos(Adr)); - recN = GetInfoRec(Adr); - if (!recN && Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (DisInfo.Call) { - Adr = DisInfo.Immediate; - Pos = Adr2Pos(Adr); - if (IsValidImageAdr(Adr)) { - if (Pos >= 0) { - SetFlag(cfLoc, Pos); - recN = GetInfoRec(Adr); - if (recN && recN->SameName("@Halt0")) { - if (fromAdr == EP && !lastAdr) - break; - } - } - /* - //Call is inside procedure (may be embedded or filled by data) - if (lastAdr && Adr > fromAdr && Adr <= lastAdr) - { - if (!IsFlagSet(cfInstruction, Pos)) - { - curAdr = Adr; - curPos = Pos; - } - else - { - curPos += instrLen; - curAdr += instrLen; - } - } - */ - } - } - curPos += instrLen; - curAdr += instrLen; - } - return curAdr - fromAdr; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::GetUnits2(String dprName) { - int instrLen, iniProcSize, pos, num, start, n; - DWORD iniAdr; - DWORD curAdr = EP; - DWORD curPos = Adr2Pos(curAdr); - PUnitRec recU; - DISINFO DisInfo; - - // Èùåì ïåðâóþ èíñòðóêöèþ call = @InitExe - n = 0; - while (1) { - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) return num; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - if (DisInfo.Call) - n++; - if (n == 2) - break; - curPos += instrLen; - curAdr += instrLen; - } - // ×èòàåì ñïèñîê âûçîâîâ (ïðîöåäóðû èíèöèàëèçàöèè) - int no = 1; - for (num = 0; ; num++) { - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) return num; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - if (!DisInfo.Call) - break; - iniAdr = DisInfo.Immediate; - iniProcSize = EstimateProcSize(iniAdr); - - recU = new UnitRec; - recU->trivial = false; - recU->trivialIni = false; - recU->trivialFin = true; - recU->kb = false; - recU->names = new TStringList; - - recU->fromAdr = 0; - recU->toAdr = 0; - recU->matchedPercent = 0.0; - recU->iniOrder = no; - no++; - - recU->toAdr = (iniAdr + iniProcSize + 3) & 0xFFFFFFFC; - - recU->finadr = 0; - recU->finSize = 0; - recU->iniadr = iniAdr; - recU->iniSize = iniProcSize; - - pos = Adr2Pos(iniAdr); - SetFlag(cfProcStart, pos); - PInfoRec recN = GetInfoRec(iniAdr); - if (!recN) - recN = new InfoRec(pos, ikProc); - recN->procInfo->procSize = iniProcSize; - - Units->Add((void*)recU); - - curPos += instrLen; - curAdr += instrLen; - } - - start = CodeBase; - num = Units->Count; - for (int i = 0; i < num; i++) { - recU = (PUnitRec)Units->Items[i]; - recU->fromAdr = start; - start = recU->toAdr; - // Last Unit has program name - if (i == num - 1) { - recU->toAdr = CodeBase + CodeSize; - SetUnitName(recU, dprName); - } - } - - return num; -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::IsExtendedInitTab(DWORD* unitsTab) { - int i, num, pos, n; - DWORD adr, initTable, iniAdr, finAdr; - - *unitsTab = 0; - for (i = 0; i < ((TotalSize - 4) & (-4)); i += 4) { - initTable = *((DWORD*)(Image + i)); - if (initTable == CodeBase + i + 4) { - num = *((DWORD*)(Image + i - 4)); - if (num <= 0 || num > 10000) - continue; - - pos = *unitsTab = i + 4; - for (n = 0; n < num; n++, pos += 8) { - iniAdr = *((DWORD*)(Image + pos)); - if (iniAdr) { - if (!IsValidImageAdr(iniAdr)) { - *unitsTab = 0; - break; - } - } - finAdr = *((DWORD*)(Image + pos + 4)); - if (finAdr) { - if (!IsValidImageAdr(finAdr)) { - *unitsTab = 0; - break; - } - } - } - if (*unitsTab) - break; - } - } - if (*unitsTab) - return false; - - // May be D2010 - *unitsTab = 0; - for (i = 0; i < ((TotalSize - 20) & (-4)); i += 4) { - initTable = *((DWORD*)(Image + i)); - if (initTable == CodeBase + i + 20) { - num = *((DWORD*)(Image + i - 4)); - if (num <= 0 || num > 10000) - continue; - - pos = *unitsTab = i + 20; - for (n = 0; n < num; n++, pos += 8) { - iniAdr = *((DWORD*)(Image + pos)); - if (iniAdr) { - if (!IsValidImageAdr(iniAdr)) { - *unitsTab = 0; - break; - } - } - finAdr = *((DWORD*)(Image + pos + 4)); - if (finAdr) { - if (!IsValidImageAdr(finAdr)) { - *unitsTab = 0; - break; - } - } - } - if (*unitsTab) - break; - } - } - if (*unitsTab) - return true; - - return false; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::GetUnits(String dprName) { - BYTE len; - char *b, *e; - int n, i, no, unitsPos = 0, start, spos, pos, iniProcSize, finProcSize, unitsNum = 0; - int typesNum, units1Num, typesTable, units1Table; // For D2010 - DWORD initTable, iniAdr, finAdr, unitsTabEnd, toAdr; - PUnitRec recU; - PInfoRec recN; - - if (DelphiVersion >= 2010) { - for (i = 0; i < ((TotalSize - 20) & (-4)); i += 4) { - initTable = *((DWORD*)(Image + i)); - if (initTable == CodeBase + i + 20) { - unitsNum = *((DWORD*)(Image + i - 4)); - if (unitsNum <= 0 || unitsNum > 10000) - continue; - - pos = unitsPos = i + 20; - for (n = 0; n < unitsNum; n++, pos += 8) { - iniAdr = *((DWORD*)(Image + pos)); - if (iniAdr && !IsValidImageAdr(iniAdr)) { - unitsPos = 0; - break; - } - finAdr = *((DWORD*)(Image + pos + 4)); - if (finAdr && !IsValidImageAdr(finAdr)) { - unitsPos = 0; - break; - } - } - if (unitsPos) - break; - } - } - } - else { - for (i = 0; i < ((CodeSize - 4) & (-4)); i += 4) { - initTable = *((DWORD*)(Image + i)); - if (initTable == CodeBase + i + 4) { - unitsNum = *((DWORD*)(Image + i - 4)); - if (unitsNum <= 0 || unitsNum > 10000) - continue; - - pos = unitsPos = i + 4; - for (n = 0; n < unitsNum; n++, pos += 8) { - iniAdr = *((DWORD*)(Image + pos)); - if (iniAdr && !IsValidImageAdr(iniAdr)) { - unitsPos = 0; - break; - } - finAdr = *((DWORD*)(Image + pos + 4)); - if (finAdr && !IsValidImageAdr(finAdr)) { - unitsPos = 0; - break; - } - } - if (unitsPos) - break; - } - } - } - // if (!unitsPos) return 0; - - if (!unitsPos) { - unitsNum = 1; - recU = new UnitRec; - recU->trivial = false; - recU->trivialIni = true; - recU->trivialFin = true; - recU->kb = false; - recU->names = new TStringList; - - recU->fromAdr = CodeBase; - recU->toAdr = CodeBase + TotalSize; - recU->matchedPercent = 0.0; - recU->iniOrder = 1; - - recU->finadr = 0; - recU->finSize = 0; - recU->iniadr = 0; - recU->iniSize = 0; - Units->Add((void*)recU); - return unitsNum; - } - - unitsTabEnd = initTable + 8 * unitsNum; - if (DelphiVersion >= 2010) { - initTable -= 24; - SetFlags(cfData, Adr2Pos(initTable), 8*unitsNum + 24); - typesNum = *((int*)(Image + Adr2Pos(initTable + 8))); - typesTable = *((int*)(Image + Adr2Pos(initTable + 12))); - SetFlags(cfData, Adr2Pos(typesTable), 4*typesNum); - units1Num = *((int*)(Image + Adr2Pos(initTable + 16))); - units1Table = *((int*)(Image + Adr2Pos(initTable + 20))); - spos = pos = Adr2Pos(units1Table); - for (i = 0; i < units1Num; i++) { - len = *(Image + pos); - pos += len + 1; - } - SetFlags(cfData, Adr2Pos(units1Table), pos - spos); - } - else { - initTable -= 8; - SetFlags(cfData, Adr2Pos(initTable), 8*unitsNum + 8); - } - - for (i = 0, no = 1; i < unitsNum; i++, unitsPos += 8) { - iniAdr = *((DWORD*)(Image + unitsPos)); - finAdr = *((DWORD*)(Image + unitsPos + 4)); - - if (!iniAdr && !finAdr) - continue; - - if (iniAdr && *((DWORD*)(Image + Adr2Pos(iniAdr))) == 0) - continue; - if (finAdr && *((DWORD*)(Image + Adr2Pos(finAdr))) == 0) - continue; - - // MAY BE REPEATED ADRESSES!!! - bool found = false; - for (n = 0; n < Units->Count; n++) { - recU = (PUnitRec)Units->Items[n]; - if (recU->iniadr == iniAdr && recU->finadr == finAdr) { - found = true; - break; - } - } - if (found) - continue; - - if (iniAdr) - iniProcSize = EstimateProcSize(iniAdr); - else - iniProcSize = 0; - - if (finAdr) - finProcSize = EstimateProcSize(finAdr); - else - finProcSize = 0; - - toAdr = 0; - if (iniAdr && iniAdr < unitsTabEnd) { - if (iniAdr >= finAdr + finProcSize) - toAdr = (iniAdr + iniProcSize + 3) & 0xFFFFFFFC; - if (finAdr >= iniAdr + iniProcSize) - toAdr = (finAdr + finProcSize + 3) & 0xFFFFFFFC; - } - else if (finAdr) { - toAdr = (finAdr + finProcSize + 3) & 0xFFFFFFFC; - } - - if (!toAdr) { - if (Units->Count > 0) - continue; - toAdr = CodeBase + CodeSize; - } - - recU = new UnitRec; - recU->trivial = false; - recU->trivialIni = true; - recU->trivialFin = true; - recU->kb = false; - recU->names = new TStringList; - - recU->fromAdr = 0; - recU->toAdr = toAdr; - recU->matchedPercent = 0.0; - recU->iniOrder = no; - no++; - - recU->finadr = finAdr; - recU->finSize = finProcSize; - recU->iniadr = iniAdr; - recU->iniSize = iniProcSize; - - if (iniAdr) { - pos = Adr2Pos(iniAdr); - // Check trivial initialization - if (iniProcSize > 8) - recU->trivialIni = false; - SetFlag(cfProcStart, pos); - // SetFlag(cfProcEnd, pos + iniProcSize - 1); - recN = GetInfoRec(iniAdr); - if (!recN) - recN = new InfoRec(pos, ikProc); - recN->procInfo->procSize = iniProcSize; - } - if (finAdr) { - pos = Adr2Pos(finAdr); - // Check trivial finalization - if (finProcSize > 46) - recU->trivialFin = false; - SetFlag(cfProcStart, pos); - // SetFlag(cfProcEnd, pos + finProcSize - 1); - recN = GetInfoRec(finAdr); - if (!recN) - recN = new InfoRec(pos, ikProc); - recN->procInfo->procSize = finProcSize; - // import? - if (IsFlagSet(cfImport, pos)) { - b = strchr(AnsiString(recN->GetName()).c_str(), '@'); - if (b) { - e = strchr(b + 1, '@'); - if (e) - SetUnitName(recU, String(b + 1, e - b - 1)); - } - } - } - Units->Add((void*)recU); - } - - Units->Sort(&SortUnitsByAdr); - - start = CodeBase; - unitsNum = Units->Count; - for (i = 0; i < unitsNum; i++) { - recU = (PUnitRec)Units->Items[i]; - recU->fromAdr = start; - if (recU->toAdr) - start = recU->toAdr; - // Is unit trivial? - if (recU->trivialIni && recU->trivialFin) { - int isize = (recU->iniSize + 3) & 0xFFFFFFFC; - int fsize = (recU->finSize + 3) & 0xFFFFFFFC; - if (isize + fsize == recU->toAdr - recU->fromAdr) - recU->trivial = true; - } - // Last Unit has program name and toAdr = initTable - if (i == unitsNum - 1) { - recU->toAdr = initTable; - SetUnitName(recU, dprName); - } - } - - return unitsNum; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::GetBCBUnits(String dprName) { - int n, pos, curPos, instrLen, iniNum, finNum, unitsNum, no; - DWORD dd, adr, curAdr, modTable, iniTable, iniTableEnd, finTable, finTableEnd, fromAdr, toAdr; - PUnitRec recU; - PInfoRec recN; - DISINFO disInfo; - - // EP: jmp @1 - curAdr = EP; - curPos = Adr2Pos(curAdr); - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &disInfo, 0); - dd = *((DWORD*)disInfo.Mnem); - if (dd == 'pmj') { - curAdr = disInfo.Immediate; - curPos = Adr2Pos(curAdr); - while (1) { - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &disInfo, 0); - dd = *((DWORD*)disInfo.Mnem); - if (dd == 'pmj') - break; - if (dd == 'hsup' && disInfo.OpType[0] == otIMM && disInfo.Immediate) { - modTable = disInfo.Immediate; - if (IsValidImageAdr(modTable)) { - pos = Adr2Pos(modTable); - iniTable = *((DWORD*)(Image + pos)); - iniTableEnd = *((DWORD*)(Image + pos + 4)); - finTable = *((DWORD*)(Image + pos + 8)); - finTableEnd = *((DWORD*)(Image + pos + 12)); - for (n = 16; n < 32; n += 4) { - adr = *((DWORD*)(Image + pos + n)); - if (IsValidImageAdr(adr)) { - pos = Adr2Pos(adr); - SetFlag(cfProcStart, pos); - recN = GetInfoRec(adr); - if (!recN) - recN = new InfoRec(pos, ikProc); - recN->SetName("WinMain"); - break; - } - } - - iniNum = (iniTableEnd - iniTable) / 6; - SetFlags(cfData, Adr2Pos(iniTable), iniTableEnd - iniTable); - finNum = (finTableEnd - finTable) / 6; - SetFlags(cfData, Adr2Pos(finTable), finTableEnd - finTable); - - TStringList* list = new TStringList; - list->Sorted = false; - list->Duplicates = System::Classes::dupIgnore; - if (iniNum > finNum) { - pos = Adr2Pos(iniTable); - for (n = 0; n < iniNum; n++) { - adr = *((DWORD*)(Image + pos + 2)); - pos += 6; - list->Add(Val2Str8(adr)); - } - } - else { - pos = Adr2Pos(finTable); - for (n = 0; n < finNum; n++) { - adr = *((DWORD*)(Image + pos + 2)); - pos += 6; - list->Add(Val2Str8(adr)); - } - } - list->Sort(); - fromAdr = CodeBase; - no = 1; - for (n = 0; n < list->Count; n++) { - recU = new UnitRec; - recU->trivial = false; - recU->trivialIni = true; - recU->trivialFin = true; - recU->kb = false; - recU->names = new TStringList; - - recU->matchedPercent = 0.0; - recU->iniOrder = no; - no++; - - toAdr = StrToInt(String("$") + list->Strings[n]); - recU->finadr = 0; - recU->finSize = 0; - recU->iniadr = toAdr; - recU->iniSize = 0; - - recU->fromAdr = fromAdr; - recU->toAdr = toAdr; - Units->Add((void*)recU); - - fromAdr = toAdr; - if (n == list->Count - 1) - SetUnitName(recU, dprName); - } - delete list; - Units->Sort(&SortUnitsByAdr); - return Units->Count; - } - } - curAdr += instrLen; - curPos += instrLen; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// -1 - not Code -// 0 - possible Code -// 1 - Code -int __fastcall TFMain_11011981::IsValidCode(DWORD fromAdr) { - BYTE op; - int firstPushReg, lastPopReg; - int firstPushPos, lastPopPos; - int row, num, instrLen, instrLen1, instrLen2; - int fromPos; - int curPos; - DWORD curAdr; - DWORD lastAdr = 0; - DWORD Adr, Adr1, Pos, lastMovAdr = 0; - PInfoRec recN; - DISINFO DisInfo; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return -1; - - if (fromAdr > EP) - return -1; - // DISPLAY - if (!stricmp(Code + fromPos, "DISPLAY")) - return -1; - - // recN = GetInfoRec(fromAdr); - int outRows = MAX_DISASSEMBLE; - if (IsFlagSet(cfImport, fromPos)) - outRows = 1; - - firstPushReg = lastPopReg = -1; - firstPushPos = lastPopPos = -1; - curPos = fromPos; - curAdr = fromAdr; - - for (row = 0; row < outRows; row++) { - // Òàáëèöà exception - if (!IsValidImageAdr(curAdr)) - return -1; - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - curPos += 4 + 8 * num; - curAdr += 4 + 8 * num; - continue; - } - - BYTE b1 = Code[curPos]; - BYTE b2 = Code[curPos + 1]; - // 00,00 - Data! - if (!b1 && !b2 && !lastAdr) - return -1; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) return -1; - if (!instrLen) // ???????? - { - curPos++; - curAdr++; - continue; - } - if (!memcmp(DisInfo.Mnem, "arpl", 4) || !memcmp(DisInfo.Mnem, "out", 3) || (DisInfo.Mnem[0] == 'i' && DisInfo.Mnem[1] == 'n' && DisInfo.Mnem[2] != 'c')) { - return -1; - } - op = Disasm.GetOp(DisInfo.Mnem); - - if (op == OP_JMP) { - if (curAdr == fromAdr) - break; - if (DisInfo.OpType[0] == otMEM) { - if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) - break; - } - if (DisInfo.OpType[0] == otIMM) { - Adr = DisInfo.Immediate; - Pos = Adr2Pos(Adr); - if (Pos < 0 && (!lastAdr || curAdr == lastAdr)) - break; - if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) - break; - if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) - break; - curAdr = Adr; - curPos = Pos; - continue; - } - } - - // Mark push or pop - if (op == OP_PUSH) { - // Åñëè ïåðâàÿ èíñòðóêöèÿ íå push reg - if (!row && DisInfo.OpType[0] != otREG) - return -1; - if (DisInfo.OpType[0] == otREG && firstPushReg == -1) { - firstPushReg = DisInfo.OpRegIdx[0]; - firstPushPos = curPos; - } - } - else if (op == OP_POP) { - if (DisInfo.OpType[0] == otREG) { - lastPopReg = DisInfo.OpRegIdx[0]; - lastPopPos = curPos; - } - } - - // Îòáðàêîâêà ïî ïåðâîé èíñòðóêöèè - if (!row) { - // Èíñòðóêöèÿ ïåðåõîäà èëè ret c àðãóìåíòàìè - if (DisInfo.Ret && DisInfo.OpNum >= 1) - return -1; - if (DisInfo.Branch) - return -1; - if (!memcmp(DisInfo.Mnem, "bound", 5) || !memcmp(DisInfo.Mnem, "retf", 4) || !memcmp(DisInfo.Mnem, "pop", 3) || !memcmp(DisInfo.Mnem, "aaa", 3) || !memcmp(DisInfo.Mnem, "adc", - 3) || !memcmp(DisInfo.Mnem, "sbb", 3) || !memcmp(DisInfo.Mnem, "rcl", 3) || !memcmp(DisInfo.Mnem, "rcr", 3) || !memcmp(DisInfo.Mnem, "clc", 3) || !memcmp(DisInfo.Mnem, "stc", 3)) - return -1; - } - // Åñëè â ïîçèöèè âñòðåòèëñÿ óæå îïðåäåëåííûé ðàíåå êîä, âûõîäèì - for (int k = 0; k < instrLen; k++) { - if (IsFlagSet(cfProcStart, curPos + k) || IsFlagSet(cfCode, curPos + k)) - return -1; - } - - if (curAdr >= lastAdr) - lastAdr = 0; - // Êîíåö ïðîöåäóðû - if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) { - // Standard frame - if (Code[fromPos] == 0x55 && Code[fromPos + 1] == 0x8B && Code[fromPos + 2] == 0xEC) - break; - if (firstPushReg == lastPopReg && firstPushPos == fromPos && lastPopPos == curPos - 1) - break; - return 0; - } - - if (op == OP_MOV) - lastMovAdr = DisInfo.Offset; - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) - // near absolute indirect jmp (Case) - { - if (!IsValidCodeAdr(DisInfo.Offset)) - break; - /* - //Ãåðâàÿ èíñòðóêöèÿ - if (curAdr == fromAdr) break; - */ - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Àäðåñ òàáëèöû - ïîñëåäíèå 4 áàéòà èíñòðóêöèè - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Àíàëèçèðóåì ïðîìåæóòîê íà ïðåäìåò òàáëèöû cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // Åñëè åñòü cTblAdr, ïðîïóñêàåì ýòó òàáëèöó - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - Pos += CNum; - Adr += CNum; - } - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Äèçàññåìáëèðóåì jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - // if (!instrLen1) return -1; - - recN = GetInfoRec(DisInfo.Immediate); - if (recN) { - if (recN->SameName("@HandleFinally")) { - // jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - /* - //@2 - Adr1 = DisInfo.Immediate - 4; - Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); - if (Adr > lastAdr) lastAdr = Adr; - */ - } - else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // Ôëàæîê cfETable, ÷òîáû ïðàâèëüíî âûâåñòè äàííûå - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Pos += 4; - // dd offset ExceptionProc - Pos += 4; - } - } - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - if (b1 == 0xEB || // short relative abs jmp or cond jmp - (b1 >= 0x70 && b1 <= 0x7F) || (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) { - Adr = DisInfo.Immediate; - if (!IsValidImageAdr(Adr)) - return -1; - if (IsValidCodeAdr(Adr)) { - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (b1 == 0xE9) // relative abs jmp or cond jmp - { - Adr = DisInfo.Immediate; - if (!IsValidImageAdr(Adr)) - return -1; - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - if (!recN && Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - curPos += instrLen; - curAdr += instrLen; - } - return 1; -} - -// --------------------------------------------------------------------------- -// Sort VmtList by height and vmtAdr -int __fastcall SortPairsCmpFunction(void *item1, void *item2) { - PVmtListRec rec1 = (PVmtListRec)item1; - PVmtListRec rec2 = (PVmtListRec)item2; - - if (rec1->height > rec2->height) - return 1; - if (rec1->height < rec2->height) - return -1; - if (rec1->vmtAdr > rec2->vmtAdr) - return 1; - if (rec1->vmtAdr < rec2->vmtAdr) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FillVmtList() { - VmtList->Clear(); - - for (int n = 0; n < TotalSize; n++) { - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->kind == ikVMT && recN->HasName()) { - PVmtListRec recV = new VmtListRec; - recV->height = GetClassHeight(Pos2Adr(n)); - recV->vmtAdr = Pos2Adr(n); - recV->vmtName = recN->GetName(); - VmtList->Add((void*)recV); - } - } - VmtList->Sort(SortPairsCmpFunction); -} - -// --------------------------------------------------------------------------- -// Return virtual method offset of procedure with address procAdr -int __fastcall TFMain_11011981::GetMethodOfs(PInfoRec rec, DWORD procAdr) { - if (rec && rec->vmtInfo->methods) { - for (int m = 0; m < rec->vmtInfo->methods->Count; m++) { - PMethodRec recM = (PMethodRec)rec->vmtInfo->methods->Items[m]; - if (recM->kind == 'V' && recM->address == procAdr) - return recM->id; - } - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return PMethodRec of method with given name -PMethodRec __fastcall TFMain_11011981::GetMethodInfo(PInfoRec rec, String name) { - if (rec && rec->vmtInfo->methods) { - for (int m = 0; m < rec->vmtInfo->methods->Count; m++) { - PMethodRec recM = (PMethodRec)rec->vmtInfo->methods->Items[m]; - if (SameText(recM->name, name)) - return recM; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// IntfTable ïðèñóòñòâóåò, åñëè êëàññ ïîðîæäåí îò èíòåðôåéñîâ -/* - Interfaces - Any class can implement any number of interfaces. The compiler stores a - table of interfaces as part of the class's RTTI. The VMT points to the table - of interfaces, which starts with a 4-byte count, followed by a list of - interface records. Each interface record contains the GUID, a pointer to the - interface's VMT, the offset to the interface's hidden field, and a pointer - to a property that implements the interface with the implements directive. - If the offset is zero, the interface property (called ImplGetter) must be - non-nil, and if the offset is not zero, ImplGetter must be nil. The interface - property can be a reference to a field, a virtual method, or a static method, - following the conventions of a property reader (which is described earlier - in this chapter, under Section 3.2.3"). When an object is constructed, Delphi - automatically checks all the interfaces, and for each interface with a - non-zero IOffset, the field at that offset is set to the interface's VTable - (a pointer to its VMT). Delphi defines the the types for the interface table, - unlike the other RTTI tables, in the System unit. These types are shown in - Example 3.9. - Example 3.9. Type Declarations for the Interface Table - - type - PInterfaceEntry = ^TInterfaceEntry; - TInterfaceEntry = record - IID: TGUID; - VTable: Pointer; - IOffset: Integer; - ImplGetter: Integer; - end; - - PInterfaceTable = ^TInterfaceTable; - TInterfaceTable = record - EntryCount: Integer; - // Declare the type with the largest possible size, - // but the true size of the array is EntryCount elements. - Entries: array[0..9999] of TInterfaceEntry; - //>=DXE2 - Intfs:array[0..EntryCount - 1] of PPTypeInfo; - end; - - TObject implements several methods for accessing the interface table. See for the details of the GetInterface, GetInterfaceEntry, and GetInterfaceTable methods. - */ -void __fastcall TFMain_11011981::ScanIntfTable(DWORD adr) { - bool vmtProc; - WORD _dx, _bx, _si; - int n, pos, entryCount, cnt, vmtOfs, vpos, _pos, iOffset; - DWORD vmtAdr, intfAdr, vAdr, iAdr, _adr; - String className, name; - PInfoRec recN, recN1; - PMethodRec recM; - BYTE GUID[16]; - - if (!IsValidImageAdr(adr)) - return; - - className = GetClsName(adr); - recN = GetInfoRec(adr); - vmtAdr = adr - VmtSelfPtr; - pos = Adr2Pos(vmtAdr) + VmtIntfTable; - intfAdr = *((DWORD*)(Code + pos)); - if (!intfAdr) - return; - - pos = Adr2Pos(intfAdr); - entryCount = *((int*)(Code + pos)); - pos += 4; - - for (n = 0; n < entryCount; n++) { - memmove(GUID, Code + pos, 16); - pos += 16; - // VTable - vAdr = *((DWORD*)(Code + pos)); - pos += 4; - if (IsValidCodeAdr(vAdr)) { - cnt = 0; - vpos = Adr2Pos(vAdr); - for (int v = 0; ; v++) { - if (IsFlagSet(cfVTable, vpos)) - cnt++; - if (cnt == 2) - break; - iAdr = *((DWORD*)(Code + vpos)); - _adr = iAdr; - _pos = Adr2Pos(_adr); - DISINFO disInfo; - vmtProc = false; - vmtOfs = 0; - _dx = 0; - _bx = 0; - _si = 0; - while (1) { - int instrlen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &disInfo, 0); - if ((disInfo.OpType[0] == otMEM || disInfo.OpType[1] == otMEM) && disInfo.BaseReg != 20) - // to exclude instruction "xchg reg, [esp]" - { - vmtOfs = disInfo.Offset; - } - if (disInfo.OpType[0] == otREG && disInfo.OpType[1] == otIMM) { - if (disInfo.OpRegIdx[0] == 10) // dx - _dx = disInfo.Immediate; - else if (disInfo.OpRegIdx[0] == 11) // bx - _bx = disInfo.Immediate; - else if (disInfo.OpRegIdx[0] == 14) // si - _si = disInfo.Immediate; - } - if (disInfo.Call) { - recN1 = GetInfoRec(disInfo.Immediate); - if (recN1) { - if (recN1->SameName("@CallDynaInst") || recN1->SameName("@CallDynaClass")) { - if (DelphiVersion <= 5) - GetDynaInfo(adr, _bx, &iAdr); - else - GetDynaInfo(adr, _si, &iAdr); - break; - } - else if (recN1->SameName("@FindDynaInst") || recN1->SameName("@FindDynaClass")) { - GetDynaInfo(adr, _dx, &iAdr); - break; - } - } - } - if (disInfo.Branch && !disInfo.Conditional) { - if (IsValidImageAdr(disInfo.Immediate)) - iAdr = disInfo.Immediate; - else - vmtProc = true; - break; - } - else if (disInfo.Ret) { - vmtProc = true; - break; - } - _pos += instrlen; - _adr += instrlen; - } - if (!vmtProc && IsValidImageAdr(iAdr)) { - AnalyzeProcInitial(iAdr); - recN1 = GetInfoRec(iAdr); - if (recN1) { - if (recN1->HasName()) { - className = ExtractClassName(recN1->GetName()); - name = ExtractProcName(recN1->GetName()); - } - else - name = GetDefaultProcName(iAdr); - if (v >= 3) { - if (!recN1->HasName()) - recN1->SetName(className + "." + name); - } - } - } - vpos += 4; - } - } - // iOffset - iOffset = *((int*)(Code + pos)); - pos += 4; - // ImplGetter - if (DelphiVersion > 3) - pos += 4; - recN->vmtInfo->AddInterface(Val2Str8(vAdr) + " " + Val2Str4(iOffset) + " " + Guid2String(GUID)); - } -} - -// --------------------------------------------------------------------------- -/* - Automated Methods - The automated section of a class declaration is now obsolete because it is - easier to create a COM automation server with Delphi's type library editor, - using interfaces. Nonetheless, the compiler currently supports automated - declarations for backward compatibility. A future version of the compiler - might drop support for automated declarations. - The OleAuto unit tells you the details of the automated method table: The - table starts with a 2-byte count, followed by a list of automation records. - Each record has a 4-byte dispid (dispatch identifier), a pointer to a short - string method name, 4-bytes of flags, a pointer to a list of parameters, - and a code pointer. The parameter list starts with a 1-byte return type, - followed by a 1-byte count of parameters, and ends with a list of 1-byte - parameter types. The parameter names are not stored. Example 3.8 shows the - declarations for the automated method table. - Example 3.8. The Layout of the Automated Method Table - - const - { Parameter type masks } - atTypeMask = $7F; - varStrArg = $48; - atByRef = $80; - MaxAutoEntries = 4095; - MaxAutoParams = 255; - - type - TVmtAutoType = Byte; - { Automation entry parameter list } - PAutoParamList = ^TAutoParamList; - TAutoParamList = packed record - ReturnType: TVmtAutoType; - Count: Byte; - Types: array[1..Count] of TVmtAutoType; - end; - { Automation table entry } - PAutoEntry = ^TAutoEntry; - TAutoEntry = packed record - DispID: LongInt; - Name: PShortString; - Flags: LongInt; { Lower byte contains flags } - Params: PAutoParamList; - Address: Pointer; - end; - - { Automation table layout } - PAutoTable = ^TAutoTable; - TAutoTable = packed record - Count: LongInt; - Entries: array[1..Count] of TAutoEntry; - end; - */ -// Auto function prototype can be recovered from AutoTable!!! -void __fastcall TFMain_11011981::ScanAutoTable(DWORD Adr) { - if (!IsValidImageAdr(Adr)) - return; - - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtAutoTable; - DWORD autoAdr = *((DWORD*)(Code + pos)); - if (!autoAdr) - return; - - String className = GetClsName(Adr); - PInfoRec recN = GetInfoRec(Adr); - - pos = Adr2Pos(autoAdr); - int entryCount = *((int*)(Code + pos)); - pos += 4; - - for (int i = 0; i < entryCount; i++) { - int dispID = *((int*)(Code + pos)); - pos += 4; - - DWORD nameAdr = *((DWORD*)(Code + pos)); - pos += 4; - DWORD posn = Adr2Pos(nameAdr); - BYTE len = *(Code + posn); - posn++; - String name = String((char*)(Code + posn), len); - String procname = className + "."; - - int flags = *((int*)(Code + pos)); - pos += 4; - DWORD params = *((int*)(Code + pos)); - pos += 4; - DWORD address = *((DWORD*)(Code + pos)); - pos += 4; - - // afVirtual - if ((flags & 8) == 0) { - // afPropGet - if (flags & 2) - procname += "Get"; - // afPropSet - if (flags & 4) - procname += "Set"; - } - else { - // virtual table function - address = *((DWORD*)(Code + Adr2Pos(vmtAdr + address))); - } - - procname += name; - AnalyzeProcInitial(address); - PInfoRec recN1 = GetInfoRec(address); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(address), ikRefine); - if (!recN1->HasName()) - recN1->SetName(procname); - // Method - if ((flags & 1) != 0) - recN1->procInfo->flags |= PF_METHOD; - // params - int ppos = Adr2Pos(params); - BYTE typeCode = *(Code + ppos); - ppos++; - BYTE paramsNum = *(Code + ppos); - ppos++; - for (int m = 0; m < paramsNum; m++) { - BYTE argType = *(Code + ppos); - ppos++; - - } - recN->vmtInfo->AddMethod(false, 'A', dispID, address, procname); - } -} - -// --------------------------------------------------------------------------- -/* - Initialization and Finalization - When Delphi constructs an object, it automatically initializes strings, - dynamic arrays, interfaces, and Variants. When the object is destroyed, - Delphi must decrement the reference counts for strings, interfaces, dynamic - arrays, and free Variants and wide strings. To keep track of this information, - Delphi uses initialization records as part of a class's RTTI. In fact, every - record and array that requires finalization has an associated initialization - record, but the compiler hides these records. The only ones you have access - to are those associated with an object's fields. - A VMT points to an initialization table. The table contains a list of - initialization records. Because arrays and records can be nested, each - initialization record contains a pointer to another initialization table, - which can contain initialization records, and so on. An initialization table - uses a TTypeKind field to keep track of whether it is initializing a string, - a record, an array, etc. - An initialization table begins with the type kind (1 byte), followed by the - type name as a short string, a 4-byte size of the data being initialized, a - 4-byte count for initialization records, and then an array of zero or more - initialization records. An initialization record is just a pointer to a - nested initialization table, followed by a 4-byte offset for the field that - must be initialized. Example 3.7 shows the logical layout of the initialization - table and record, but the declarations depict the logical layout without - being true Pascal code. - Example 3.7. The Layout of the Initialization Table and Record - - type - { Initialization/finalization record } - PInitTable = ^TInitTable; - TInitRecord = packed record - InitTable: ^PInitTable; - Offset: LongWord; // Offset of field in object - end; - { Initialization/finalization table } - TInitTable = packed record - {$MinEnumSize 1} // Ensure that TypeKind takes up 1 byte. - TypeKind: TTypeKind; - TypeName: packed ShortString; - DataSize: LongWord; - Count: LongWord; - // If TypeKind=ikArray, Count is the array size, but InitRecords - // has only one element; if the type kind is tkRecord, Count is the - // number of record members, and InitRecords[] has a - // record for each member. For all other types, Count=0. - InitRecords: array[1..Count] of TInitRecord; - end; - */ -void __fastcall TFMain_11011981::ScanInitTable(DWORD Adr) { - if (!IsValidImageAdr(Adr)) - return; - - PInfoRec recN = GetInfoRec(Adr); - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtInitTable; - DWORD initAdr = *((DWORD*)(Code + pos)); - if (!initAdr) - return; - - pos = Adr2Pos(initAdr); - pos++; // skip 0xE - pos++; // unknown - pos += 4; // unknown - DWORD num = *((DWORD*)(Code + pos)); - pos += 4; - - for (int i = 0; i < num; i++) { - DWORD typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - DWORD post = Adr2Pos(typeAdr); - if (DelphiVersion != 2) - post += 4; // skip SelfPtr - post++; // skip tkKind - BYTE len = *(Code + post); - post++; - String typeName = String((char*)&Code[post], len); - int fieldOfs = *((int*)(Code + pos)); - pos += 4; - recN->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, "", typeName); - } -} - -// --------------------------------------------------------------------------- -// For Version>=2010 -// Count: Word; // Published fields -// ClassTab: PVmtFieldClassTab -// Entry: array[1..Count] of TVmtFieldEntry -// ExCount: Word; -// ExEntry: array[1..ExCount] of TVmtFieldExEntry; -// ================================================ -// TVmtFieldEntry -// FieldOffset: Longword; -// TypeIndex: Word; // index into ClassTab -// Name: ShortString; -// ================================================ -// TFieldExEntry = packed record -// Flags: Byte; -// TypeRef: PPTypeInfo; -// Offset: Longword; -// Name: ShortString; -// AttrData: TAttrData -void __fastcall TFMain_11011981::ScanFieldTable(DWORD Adr) { - if (!IsValidImageAdr(Adr)) - return; - - PInfoRec recN = GetInfoRec(Adr); - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtFieldTable; - DWORD fieldAdr = *((DWORD*)(Code + pos)); - if (!fieldAdr) - return; - - pos = Adr2Pos(fieldAdr); - WORD count = *((WORD*)(Code + pos)); - pos += 2; - DWORD typesTab = *((DWORD*)(Code + pos)); - pos += 4; - - for (int i = 0; i < count; i++) { - int fieldOfs = *((int*)(Code + pos)); - pos += 4; - WORD idx = *((WORD*)(Code + pos)); - pos += 2; - BYTE len = Code[pos]; - pos++; - String name = String((char*)(Code + pos), len); - pos += len; - - DWORD post = Adr2Pos(typesTab) + 2 + 4 * idx; - DWORD classAdr = *((DWORD*)(Code + post)); - if (IsFlagSet(cfImport, Adr2Pos(classAdr))) { - PInfoRec recN1 = GetInfoRec(classAdr); - recN->vmtInfo->AddField(0, 0, FIELD_PUBLISHED, fieldOfs, -1, name, recN1->GetName()); - } - else { - if (DelphiVersion == 2) - classAdr += VmtSelfPtr; - recN->vmtInfo->AddField(0, 0, FIELD_PUBLISHED, fieldOfs, -1, name, GetClsName(classAdr)); - } - } - if (DelphiVersion >= 2010) { - WORD exCount = *((WORD*)(Code + pos)); - pos += 2; - for (int i = 0; i < exCount; i++) { - BYTE flags = Code[pos]; - pos++; - DWORD typeRef = *((DWORD*)(Code + pos)); - pos += 4; - int offset = *((int*)(Code + pos)); - pos += 4; - BYTE len = Code[pos]; - pos++; - String name = String((char*)(Code + pos), len); - pos += len; - WORD dw = *((WORD*)(Code + pos)); - pos += dw; - recN->vmtInfo->AddField(0, 0, FIELD_PUBLISHED, offset, -1, name, GetTypeName(typeRef)); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ScanMethodTable(DWORD adr, String className) { - BYTE len; - WORD skipNext; - DWORD codeAdr; - int spos, pos; - String name, methodName; - - if (!IsValidImageAdr(adr)) - return; - - DWORD vmtAdr = adr - VmtSelfPtr; - DWORD methodAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr) + VmtMethodTable)); - if (!methodAdr) - return; - - pos = Adr2Pos(methodAdr); - WORD count = *((WORD*)(Code + pos)); - pos += 2; - - for (int n = 0; n < count; n++) { - spos = pos; - skipNext = *((WORD*)(Code + pos)); - pos += 2; - codeAdr = *((DWORD*)(Code + pos)); - pos += 4; - len = Code[pos]; - pos++; - name = String((char*)&Code[pos], len); - pos += len; - - // as added why this code was removed? - methodName = className + "." + name; - DWORD pos1 = Adr2Pos(codeAdr); - PInfoRec recN1 = GetInfoRec(codeAdr); - if (!recN1) { - recN1 = new InfoRec(pos1, ikRefine); - recN1->SetName(methodName); - } - // ~ - - Infos[Adr2Pos(adr)]->vmtInfo->AddMethod(false, 'M', -1, codeAdr, methodName); - pos = spos + skipNext; - } - if (DelphiVersion >= 2010) { - WORD exCount = *((WORD*)(Code + pos)); - pos += 2; - for (int n = 0; n < exCount; n++) { - // Entry - DWORD entry = *((DWORD*)(Code + pos)); - pos += 4; - // Flags - pos += 2; - // VirtualIndex - pos += 2; - spos = pos; - // Entry - pos = Adr2Pos(entry); - skipNext = *((WORD*)(Code + pos)); - pos += 2; - codeAdr = *((DWORD*)(Code + pos)); - pos += 4; - len = Code[pos]; - pos++; - name = String((char*)&Code[pos], len); - pos += len; - Infos[Adr2Pos(adr)]->vmtInfo->AddMethod(false, 'M', -1, codeAdr, className + "." + name); - pos = spos; - } - } -} -// --------------------------------------------------------------------------- -typedef struct { - int id; - char *typname; - char *msgname; -} MsgInfo, *PMsgMInfo; - -MsgInfo WindowsMsgTab[] = { - {1, "WMCreate", "WM_CREATE"}, {2, "WMDestroy", "WM_DESTROY"}, {3, "WMMove", "WM_MOVE"}, {5, "WMSize", "WM_SIZE"}, {6, "WMActivate", "WM_ACTIVATE"}, {7, "WMSetFocus", "WM_SETFOCUS"}, - {8, "WMKillFocus", "WM_KILLFOCUS"}, {0xA, "WMEnable", "WM_ENABLE"}, {0xB, "WMSetRedraw", "WM_SETREDRAW"}, {0xC, "WMSetText", "WM_SETTEXT"}, {0xD, "WMGetText", "WM_GETTEXT"}, - {0xE, "WMGetTextLength", "WM_GETTEXTLENGTH"}, {0xF, "WMPaint", "WM_PAINT"}, {0x10, "WMClose", "WM_CLOSE"}, {0x11, "WMQueryEndSession", "WM_QUERYENDSESSION"}, {0x12, "WMQuit", "WM_QUIT"}, - {0x13, "WMQueryOpen", "WM_QUERYOPEN"}, {0x14, "WMEraseBkgnd", "WM_ERASEBKGND"}, {0x15, "WMSysColorChange", "WM_SYSCOLORCHANGE"}, {0x16, "WMEndSession", "WM_ENDSESSION"}, - {0x17, "WMSystemError", "WM_SYSTEMERROR"}, {0x18, "WMShowWindow", "WM_SHOWWINDOW"}, {0x19, "WMCtlColor", "WM_CTLCOLOR"}, {0x1A, "WMSettingChange", "WM_SETTINGCHANGE"}, - {0x1B, "WMDevModeChange", "WM_DEVMODECHANGE"}, {0x1C, "WMActivateApp", "WM_ACTIVATEAPP"}, {0x1D, "WMFontChange", "WM_FONTCHANGE"}, {0x1E, "WMTimeChange", "WM_TIMECHANGE"}, - {0x1F, "WMCancelMode", "WM_CANCELMODE"}, {0x20, "WMSetCursor", "WM_SETCURSOR"}, {0x21, "WMMouseActivate", "WM_MOUSEACTIVATE"}, {0x22, "WMChildActivate", "WM_CHILDACTIVATE"}, - {0x23, "WMQueueSync", "WM_QUEUESYNC"}, {0x24, "WMGetMinMaxInfo", "WM_GETMINMAXINFO"}, {0x26, "WMPaintIcon", "WM_PAINTICON"}, {0x27, "WMEraseBkgnd", "WM_ICONERASEBKGND"}, - {0x28, "WMNextDlgCtl", "WM_NEXTDLGCTL"}, {0x2A, "WMSpoolerStatus", "WM_SPOOLERSTATUS"}, {0x2B, "WMDrawItem", "WM_DRAWITEM"}, {0x2C, "WMMeasureItem", "WM_MEASUREITEM"}, - {0x2D, "WMDeleteItem", "WM_DELETEITEM"}, {0x2E, "WMVKeyToItem", "WM_VKEYTOITEM"}, {0x2F, "WMCharToItem", "WM_CHARTOITEM"}, {0x30, "WMSetFont", "WM_SETFONT"}, {0x31, "WMGetFont", "WM_GETFONT"}, - {0x32, "WMSetHotKey", "WM_SETHOTKEY"}, {0x33, "WMGetHotKey", "WM_GETHOTKEY"}, {0x37, "WMQueryDragIcon", "WM_QUERYDRAGICON"}, {0x39, "WMCompareItem", "WM_COMPAREITEM"}, - // {0x3D, "?", "WM_GETOBJECT"}, - {0x41, "WMCompacting", "WM_COMPACTING"}, - // {0x44, "?", "WM_COMMNOTIFY"}, - {0x46, "WMWindowPosChangingMsg", "WM_WINDOWPOSCHANGING"}, {0x47, "WMWindowPosChangedMsg", "WM_WINDOWPOSCHANGED"}, {0x48, "WMPower", "WM_POWER"}, {0x4A, "WMCopyData", "WM_COPYDATA"}, - // {0x4B, "?", "WM_CANCELJOURNAL"}, - {0x4E, "WMNotify", "WM_NOTIFY"}, - // {0x50, "?", "WM_INPUTLANGCHANGEREQUEST"}, - // {0x51, "?", "WM_INPUTLANGCHANGE"}, - // {0x52, "?", "WM_TCARD"}, - {0x53, "WMHelp", "WM_HELP"}, - // {0x54, "?", "WM_USERCHANGED"}, - {0x55, "WMNotifyFormat", "WM_NOTIFYFORMAT"}, {0x7B, "WMContextMenu", "WM_CONTEXTMENU"}, {0x7C, "WMStyleChanging", "WM_STYLECHANGING"}, {0x7D, "WMStyleChanged", "WM_STYLECHANGED"}, - {0x7E, "WMDisplayChange", "WM_DISPLAYCHANGE"}, {0x7F, "WMGetIcon", "WM_GETICON"}, {0x80, "WMSetIcon", "WM_SETICON"}, {0x81, "WMNCCreate", "WM_NCCREATE"}, {0x82, "WMNCDestroy", "WM_NCDESTROY"}, - {0x83, "WMNCCalcSize", "WM_NCCALCSIZE"}, {0x84, "WMNCHitTest", "WM_NCHITTEST"}, {0x85, "WMNCPaint", "WM_NCPAINT"}, {0x86, "WMNCActivate", "WM_NCACTIVATE"}, {0x87, "WMGetDlgCode", "WM_GETDLGCODE"}, - {0xA0, "WMNCMouseMove", "WM_NCMOUSEMOVE"}, {0xA1, "WMNCLButtonDown", "WM_NCLBUTTONDOWN"}, {0xA2, "WMNCLButtonUp", "WM_NCLBUTTONUP"}, {0xA3, "WMNCLButtonDblClk", "WM_NCLBUTTONDBLCLK"}, - {0xA4, "WMNCRButtonDown", "WM_NCRBUTTONDOWN"}, {0xA5, "WMNCRButtonUp", "WM_NCRBUTTONUP"}, {0xA6, "WMNCRButtonDblClk", "WM_NCRBUTTONDBLCLK"}, {0xA7, "WMNCMButtonDown", "WM_NCMBUTTONDOWN"}, - {0xA8, "WMNCMButtonUp", "WM_NCMBUTTONUP"}, {0xA9, "WMNCMButtonDblClk", "WM_NCMBUTTONDBLCLK"}, {0x100, "WMKeyDown", "WM_KEYDOWN"}, {0x101, "WMKeyUp", "WM_KEYUP"}, {0x102, "WMChar", "WM_CHAR"}, - {0x103, "WMDeadChar", "WM_DEADCHAR"}, {0x104, "WMSysKeyDown", "WM_SYSKEYDOWN"}, {0x105, "WMSysKeyUp", "WM_SYSKEYUP"}, {0x106, "WMSysChar", "WM_SYSCHAR"}, - {0x107, "WMSysDeadChar", "WM_SYSDEADCHAR"}, - // {0x108, "?", "WM_KEYLAST"}, - // {0x10D, "?", "WM_IME_STARTCOMPOSITION"}, - // {0x10E, "?", "WM_IME_ENDCOMPOSITION"}, - // {0x10F, "?", "WM_IME_COMPOSITION"}, - {0x110, "WMInitDialog", "WM_INITDIALOG"}, {0x111, "WMCommand", "WM_COMMAND"}, {0x112, "WMSysCommand", "WM_SYSCOMMAND"}, {0x113, "WMTimer", "WM_TIMER"}, {0x114, "WMHScroll", "WM_HSCROLL"}, - {0x115, "WMVScroll", "WM_VSCROLL"}, {0x116, "WMInitMenu", "WM_INITMENU"}, {0x117, "WMInitMenuPopup", "WM_INITMENUPOPUP"}, {0x11F, "WMMenuSelect", "WM_MENUSELECT"}, - {0x120, "WMMenuChar", "WM_MENUCHAR"}, {0x121, "WMEnterIdle", "WM_ENTERIDLE"}, - // {0x122, "?", "WM_MENURBUTTONUP"}, - // {0x123, "?", "WM_MENUDRAG"}, - // {0x124, "?", "WM_MENUGETOBJECT"}, - // {0x125, "?", "WM_UNINITMENUPOPUP"}, - // {0x126, "?", "WM_MENUCOMMAND"}, - {0x127, "WMChangeUIState", "WM_CHANGEUISTATE"}, {0x128, "WMUpdateUIState", "WM_UPDATEUISTATE"}, {0x129, "WMQueryUIState", "WM_QUERYUISTATE"}, {0x132, "WMCtlColorMsgBox", "WM_CTLCOLORMSGBOX"}, - {0x133, "WMCtlColorEdit", "WM_CTLCOLOREDIT"}, {0x134, "WMCtlColorListBox", "WM_CTLCOLORLISTBOX"}, {0x135, "WMCtlColorBtn", "WM_CTLCOLORBTN"}, {0x136, "WMCtlColorDlg", "WM_CTLCOLORDLG"}, - {0x137, "WMCtlColorScrollBar", "WM_CTLCOLORSCROLLBAR"}, {0x138, "WMCtlColorStatic", "WM_CTLCOLORSTATIC"}, {0x200, "WMMouseMove", "WM_MOUSEMOVE"}, {0x201, "WMLButtonDown", "WM_LBUTTONDOWN"}, - {0x202, "WMLButtonUp", "WM_LBUTTONUP"}, {0x203, "WMLButtonDblClk", "WM_LBUTTONDBLCLK"}, {0x204, "WMRButtonDown", "WM_RBUTTONDOWN"}, {0x205, "WMRButtonUp", "WM_RBUTTONUP"}, - {0x206, "WMRButtonDblClk", "WM_RBUTTONDBLCLK"}, {0x207, "WMMButtonDown", "WM_MBUTTONDOWN"}, {0x208, "WMMButtonUp", "WM_MBUTTONUP"}, {0x209, "WMMButtonDblClk", "WM_MBUTTONDBLCLK"}, - {0x20A, "WMMouseWheel", "WM_MOUSEWHEEL"}, {0x210, "WMParentNotify", "WM_PARENTNOTIFY"}, {0x211, "WMEnterMenuLoop", "WM_ENTERMENULOOP"}, {0x212, "WMExitMenuLoop", "WM_EXITMENULOOP"}, - // {0x213, "?", "WM_NEXTMENU"}, - // {0x214, "?", "WM_SIZING"}, - // {0x215, "?", "WM_CAPTURECHANGED"}, - // {0x216, "?", "WM_MOVING"}, - // {0x218, "?", "WM_POWERBROADCAST"}, - // {0x219, "?", "WM_DEVICECHANGE"}, - {0x220, "WMMDICreate", "WM_MDICREATE"}, {0x221, "WMMDIDestroy", "WM_MDIDESTROY"}, {0x222, "WMMDIActivate", "WM_MDIACTIVATE"}, {0x223, "WMMDIRestore", "WM_MDIRESTORE"}, - {0x224, "WMMDINext", "WM_MDINEXT"}, {0x225, "WMMDIMaximize", "WM_MDIMAXIMIZE"}, {0x226, "WMMDITile", "WM_MDITILE"}, {0x227, "WMMDICascade", "WM_MDICASCADE"}, - {0x228, "WMMDIIconArrange", "WM_MDIICONARRANGE"}, {0x229, "WMMDIGetActive", "WM_MDIGETACTIVE"}, {0x230, "WMMDISetMenu", "WM_MDISETMENU"}, - // {0x231, "?", "WM_ENTERSIZEMOVE"}, - // {0x232, "?", "WM_EXITSIZEMOVE"}, - {0x233, "WMDropFiles", "WM_DROPFILES"}, {0x234, "WMMDIRefreshMenu", "WM_MDIREFRESHMENU"}, - // {0x281, "?", "WM_IME_SETCONTEXT"}, - // {0x282, "?", "WM_IME_NOTIFY"}, - // {0x283, "?", "WM_IME_CONTROL"}, - // {0x284, "?", "WM_IME_COMPOSITIONFULL"}, - // {0x285, "?", "WM_IME_SELECT"}, - // {0x286, "?", "WM_IME_CHAR"}, - // {0x288, "?", "WM_IME_REQUEST"}, - // {0x290, "?", "WM_IME_KEYDOWN"}, - // {0x291, "?", "WM_IME_KEYUP"}, - // {0x2A1, "?", "WM_MOUSEHOVER"}, - // {0x2A3, "?", "WM_MOUSELEAVE"}, - {0x300, "WMCut", "WM_CUT"}, {0x301, "WMCopy", "WM_COPY"}, {0x302, "WMPaste", "WM_PASTE"}, {0x303, "WMClear", "WM_CLEAR"}, {0x304, "WMUndo", "WM_UNDO"}, {0x305, "WMRenderFormat", "WM_RENDERFORMAT" - }, {0x306, "WMRenderAllFormats", "WM_RENDERALLFORMATS"}, {0x307, "WMDestroyClipboard", "WM_DESTROYCLIPBOARD"}, {0x308, "WMDrawClipboard", "WM_DRAWCLIPBOARD"}, - {0x309, "WMPaintClipboard", "WM_PAINTCLIPBOARD"}, {0x30A, "WMVScrollClipboard", "WM_VSCROLLCLIPBOARD"}, {0x30B, "WMSizeClipboard", "WM_SIZECLIPBOARD"}, - {0x30C, "WMAskCBFormatName", "WM_ASKCBFORMATNAME"}, {0x30D, "WMChangeCBChain", "WM_CHANGECBCHAIN"}, {0x30E, "WMHScrollClipboard", "WM_HSCROLLCLIPBOARD"}, - {0x30F, "WMQueryNewPalette", "WM_QUERYNEWPALETTE"}, {0x310, "WMPaletteIsChanging", "WM_PALETTEISCHANGING"}, {0x311, "WMPaletteChanged", "WM_PALETTECHANGED"}, {0x312, "WMHotKey", "WM_HOTKEY"}, - // {0x317, "?", "WM_PRINT"}, - // {0x318, "?", "WM_PRINTCLIENT"}, - // {0x358, "?", "WM_HANDHELDFIRST"}, - // {0x35F, "?", "WM_HANDHELDLAST"}, - // {0x380, "?", "WM_PENWINFIRST"}, - // {0x38F, "?", "WM_PENWINLAST"}, - // {0x390, "?", "WM_COALESCE_FIRST"}, - // {0x39F, "?", "WM_COALESCE_LAST"}, - {0x3E0, "WMDDE_Initiate", "WM_DDE_INITIATE"}, {0x3E1, "WMDDE_Terminate", "WM_DDE_TERMINATE"}, {0x3E2, "WMDDE_Advise", "WM_DDE_ADVISE"}, {0x3E3, "WMDDE_UnAdvise", "WM_DDE_UNADVISE"}, - {0x3E4, "WMDDE_Ack", "WM_DDE_ACK"}, {0x3E5, "WMDDE_Data", "WM_DDE_DATA"}, {0x3E6, "WMDDE_Request", "WM_DDE_REQUEST"}, {0x3E7, "WMDDE_Poke", "WM_DDE_POKE"}, - {0x3E8, "WMDDE_Execute", "WM_DDE_EXECUTE"}, {0, ""}}; - -MsgInfo VCLControlsMsgTab[] = { - {0xB000, "CMActivate", "CM_ACTIVATE"}, {0xB001, "CMDeactivate", "CM_DEACTIVATE"}, {0xB002, "CMGotFocus", "CM_GOTFOCUS"}, {0xB003, "CMLostFocus", "CM_LOSTFOCUS"}, - {0xB004, "CMCancelMode", "CM_CANCELMODE"}, {0xB005, "CMDialogKey", "CM_DIALOGKEY"}, {0xB006, "CMDialogChar", "CM_DIALOGCHAR"}, {0xB007, "CMFocusChenged", "CM_FOCUSCHANGED"}, - {0xB008, "CMParentFontChanged", "CM_PARENTFONTCHANGED"}, {0xB009, "CMParentColorChanged", "CM_PARENTCOLORCHANGED"}, {0xB00A, "CMHitTest", "CM_HITTEST"}, - {0xB00B, "CMVisibleChanged", "CM_VISIBLECHANGED"}, {0xB00C, "CMEnabledChanged", "CM_ENABLEDCHANGED"}, {0xB00D, "CMColorChanged", "CM_COLORCHANGED"}, {0xB00E, "CMFontChanged", "CM_FONTCHANGED"}, - {0xB00F, "CMCursorChanged", "CM_CURSORCHANGED"}, {0xB010, "CMCtl3DChanged", "CM_CTL3DCHANGED"}, {0xB011, "CMParentCtl3DChanged", "CM_PARENTCTL3DCHANGED"}, - {0xB012, "CMTextChanged", "CM_TEXTCHANGED"}, {0xB013, "CMMouseEnter", "CM_MOUSEENTER"}, {0xB014, "CMMouseLeave", "CM_MOUSELEAVE"}, {0xB015, "CMMenuChanged", "CM_MENUCHANGED"}, - {0xB016, "CMAppKeyDown", "CM_APPKEYDOWN"}, {0xB017, "CMAppSysCommand", "CM_APPSYSCOMMAND"}, {0xB018, "CMButtonPressed", "CM_BUTTONPRESSED"}, {0xB019, "CMShowingChanged", "CM_SHOWINGCHANGED"}, - {0xB01A, "CMEnter", "CM_ENTER"}, {0xB01B, "CMExit", "CM_EXIT"}, {0xB01C, "CMDesignHitTest", "CM_DESIGNHITTEST"}, {0xB01D, "CMIconChanged", "CM_ICONCHANGED"}, - {0xB01E, "CMWantSpecialKey", "CM_WANTSPECIALKEY"}, {0xB01F, "CMInvokeHelp", "CM_INVOKEHELP"}, {0xB020, "CMWondowHook", "CM_WINDOWHOOK"}, {0xB021, "CMRelease", "CM_RELEASE"}, - {0xB022, "CMShowHintChanged", "CM_SHOWHINTCHANGED"}, {0xB023, "CMParentShowHintChanged", "CM_PARENTSHOWHINTCHANGED"}, {0xB024, "CMSysColorChange", "CM_SYSCOLORCHANGE"}, - {0xB025, "CMWinIniChange", "CM_WININICHANGE"}, {0xB026, "CMFontChange", "CM_FONTCHANGE"}, {0xB027, "CMTimeChange", "CM_TIMECHANGE"}, {0xB028, "CMTabStopChanged", "CM_TABSTOPCHANGED"}, - {0xB029, "CMUIActivate", "CM_UIACTIVATE"}, {0xB02A, "CMUIDeactivate", "CM_UIDEACTIVATE"}, {0xB02B, "CMDocWindowActivate", "CM_DOCWINDOWACTIVATE"}, - {0xB02C, "CMControlLIstChange", "CM_CONTROLLISTCHANGE"}, {0xB02D, "CMGetDataLink", "CM_GETDATALINK"}, {0xB02E, "CMChildKey", "CM_CHILDKEY"}, {0xB02F, "CMDrag", "CM_DRAG"}, - {0xB030, "CMHintShow", "CM_HINTSHOW"}, {0xB031, "CMDialogHanlde", "CM_DIALOGHANDLE"}, {0xB032, "CMIsToolControl", "CM_ISTOOLCONTROL"}, {0xB033, "CMRecreateWnd", "CM_RECREATEWND"}, - {0xB034, "CMInvalidate", "CM_INVALIDATE"}, {0xB035, "CMSysFontChanged", "CM_SYSFONTCHANGED"}, {0xB036, "CMControlChange", "CM_CONTROLCHANGE"}, {0xB037, "CMChanged", "CM_CHANGED"}, - {0xB038, "CMDockClient", "CM_DOCKCLIENT"}, {0xB039, "CMUndockClient", "CM_UNDOCKCLIENT"}, {0xB03A, "CMFloat", "CM_FLOAT"}, {0xB03B, "CMBorderChanged", "CM_BORDERCHANGED"}, - {0xB03C, "CMBiDiModeChanged", "CM_BIDIMODECHANGED"}, {0xB03D, "CMParentBiDiModeChanged", "CM_PARENTBIDIMODECHANGED"}, {0xB03E, "CMAllChildrenFlipped", "CM_ALLCHILDRENFLIPPED"}, - {0xB03F, "CMActionUpdate", "CM_ACTIONUPDATE"}, {0xB040, "CMActionExecute", "CM_ACTIONEXECUTE"}, {0xB041, "CMHintShowPause", "CM_HINTSHOWPAUSE"}, - {0xB044, "CMDockNotification", "CM_DOCKNOTIFICATION"}, {0xB043, "CMMouseWheel", "CM_MOUSEWHEEL"}, {0xB044, "CMIsShortcut", "CM_ISSHORTCUT"}, {0xB045, "CMRawX11Event", "CM_RAWX11EVENT"}, - {0, "", ""}}; - -PMsgMInfo __fastcall GetMsgInfo(WORD msg) { - // WindowsMsgTab - if (msg < 0x400) { - for (int m = 0; ; m++) { - if (!WindowsMsgTab[m].id) - break; - if (WindowsMsgTab[m].id == msg) - return &WindowsMsgTab[m]; - } - } - // VCLControlsMsgTab - if (msg >= 0xB000 && msg < 0xC000) { - for (int m = 0; ; m++) { - if (!VCLControlsMsgTab[m].id) - break; - if (VCLControlsMsgTab[m].id == msg) - return &VCLControlsMsgTab[m]; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ScanDynamicTable(DWORD adr) { - PInfoRec recN, recN1, recN2; - - if (!IsValidImageAdr(adr)) - return; - - recN = GetInfoRec(adr); - - if (!recN) - return; - - DWORD vmtAdr = adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtDynamicTable; - DWORD dynamicAdr = *((DWORD*)(Code + pos)); - if (!dynamicAdr) - return; - - String className = GetClsName(adr); - - pos = Adr2Pos(dynamicAdr); - WORD num = *((WORD*)(Code + pos)); - pos += 2; - DWORD post = pos + 2 * num; - // First fill wellknown names - for (int i = 0; i < num; i++) { - WORD msg = *((WORD*)(Code + pos)); - pos += 2; - DWORD procAdr = *((DWORD*)(Code + post)); - post += 4; - MethodRec recM; - recM.abstract = false; - recM.kind = 'D'; - recM.id = (int)msg; - recM.address = procAdr; - recM.name = ""; - - recN1 = GetInfoRec(procAdr); - if (recN1 && recN1->HasName()) - recM.name = recN1->GetName(); - else { - PMsgMInfo _info = GetMsgInfo(msg); - if (_info) { - String typname = _info->typname; - if (typname != "") { - if (!recN1) - recN1 = new InfoRec(Adr2Pos(procAdr), ikRefine); - recM.name = className + "." + typname; - recN1->SetName(recM.name); - } - } - if (recM.name == "") { - DWORD parentAdr = GetParentAdr(adr); - while (parentAdr) { - recN2 = GetInfoRec(parentAdr); - if (recN2) { - DWORD vmtAdr1 = parentAdr - VmtSelfPtr; - DWORD pos1 = Adr2Pos(vmtAdr1) + VmtDynamicTable; - dynamicAdr = *((DWORD*)(Code + pos1)); - if (dynamicAdr) { - pos1 = Adr2Pos(dynamicAdr); - WORD num1 = *((WORD*)(Code + pos1)); - pos1 += 2; - DWORD post1 = pos1 + 2 * num1; - - for (int j = 0; j < num1; j++) { - WORD msg1 = *((WORD*)(Code + pos1)); - pos1 += 2; - DWORD procAdr1 = *((DWORD*)(Code + post1)); - post1 += 4; - if (msg1 == msg) { - recN2 = GetInfoRec(procAdr1); - if (recN2 && recN2->HasName()) { - int dpos = recN2->GetName().Pos("."); - if (dpos) - recM.name = className + recN2->GetName().SubString(dpos, recN2->GetNameLength() - dpos + 1); - else - recM.name = recN2->GetName(); - } - break; - } - } - if (recM.name != "") - break; - } - } - parentAdr = GetParentAdr(parentAdr); - } - } - - if (recM.name == "" || SameText(recM.name, "@AbstractError")) - recM.name = className + ".sub_" + Val2Str8(recM.address); - - recN1 = new InfoRec(Adr2Pos(procAdr), ikRefine); - recN1->SetName(recM.name); - } - recN->vmtInfo->AddMethod(recM.abstract, recM.kind, recM.id, recM.address, recM.name); - } -} - -// --------------------------------------------------------------------------- -bool __fastcall IsOwnVirtualMethod(DWORD vmtAdr, DWORD procAdr) { - DWORD parentAdr = GetParentAdr(vmtAdr); - if (!parentAdr) - return true; - DWORD stopAt = GetStopAt(parentAdr - VmtSelfPtr); - if (vmtAdr == stopAt) - return false; - - int pos = Adr2Pos(parentAdr) + VmtParent + 4; - - for (int m = VmtParent + 4; ; m += 4, pos += 4) { - if (Pos2Adr(pos) == stopAt) - break; - - if (*((DWORD*)(Code + pos)) == procAdr) - return false; - } - return true; -} - -// --------------------------------------------------------------------------- -// Create recN->methods list -void __fastcall TFMain_11011981::ScanVirtualTable(DWORD adr) { - int m, pos, idx; - DWORD vmtAdr, stopAt; - String clsName; - PInfoRec recN, recN1; - MethodRec recM; - MProcInfo aInfo; - MProcInfo* pInfo = &aInfo; - - if (!IsValidImageAdr(adr)) - return; - clsName = GetClsName(adr); - vmtAdr = adr - VmtSelfPtr; - stopAt = GetStopAt(vmtAdr); - if (vmtAdr == stopAt) - return; - - pos = Adr2Pos(vmtAdr) + VmtParent + 4; - recN = GetInfoRec(vmtAdr + VmtSelfPtr); - - for (m = VmtParent + 4; ; m += 4, pos += 4) { - if (Pos2Adr(pos) == stopAt) - break; - - recM.abstract = false; - recM.address = *((DWORD*)(Code + pos)); - - recN1 = GetInfoRec(recM.address); - if (recN1 && recN1->HasName()) { - if (recN1->HasName()) { - if (!recN1->SameName("@AbstractError")) { - recM.name = recN1->GetName(); - } - else { - recM.abstract = true; - recM.name = ""; - } - } - } - else { - recM.name = ""; - if (m == VmtFreeInstance) - recM.name = clsName + "." + "FreeInstance"; - else if (m == VmtNewInstance) - recM.name = clsName + "." + "NewInstance"; - else if (m == VmtDefaultHandler) - recM.name = clsName + "." + "DefaultHandler"; - if (DelphiVersion == 3 && m == VmtSafeCallException) - recM.name = clsName + "." + "SafeCallException"; - if (DelphiVersion >= 4) { - if (m == VmtSafeCallException) - recM.name = clsName + "." + "SafeCallException"; - else if (m == VmtAfterConstruction) - recM.name = clsName + "." + "AfterConstruction"; - else if (m == VmtBeforeDestruction) - recM.name = clsName + "." + "BeforeDestruction"; - else if (m == VmtDispatch) - recM.name = clsName + "." + "Dispatch"; - } - if (DelphiVersion >= 2009) { - if (m == VmtEquals) - recM.name = clsName + "." + "Equals"; - else if (m == VmtGetHashCode) - recM.name = clsName + "." + "GetHashCode"; - else if (m == VmtToString) - recM.name = clsName + "." + "ToString"; - } - if (recM.name != "" && KnowledgeBase.GetKBProcInfo(recM.name, pInfo, &idx)) - StrapProc(Adr2Pos(recM.address), idx, pInfo, true, pInfo->DumpSz); - } - recN->vmtInfo->AddMethod(recM.abstract, 'V', m, recM.address, recM.name); - } -} - -// --------------------------------------------------------------------------- -// Âîçâðàùàåò "âûñîòó" êëàññà (÷èñëî ðîäèòåëüñêèõ êëàññîâ äî 0) -int __fastcall TFMain_11011981::GetClassHeight(DWORD adr) { - int level = 0; - while (1) { - adr = GetParentAdr(adr); - if (!adr) - break; - level++; - } - - return level; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::PropagateVMTNames(DWORD adr) { - String className = GetClsName(adr); - PInfoRec recN = GetInfoRec(adr); - - DWORD vmtAdr = adr - VmtSelfPtr; - DWORD stopAt = GetStopAt(vmtAdr); - if (vmtAdr == stopAt) - return; - - int pos = Adr2Pos(vmtAdr) + VmtParent + 4; - for (int m = VmtParent + 4; ; m += 4, pos += 4) { - if (Pos2Adr(pos) == stopAt) - break; - - DWORD procAdr = *((DWORD*)(Code + pos)); - PInfoRec recN1 = GetInfoRec(procAdr); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(procAdr), ikRefine); - - if (!recN1->HasName()) { - DWORD classAdr = adr; - while (classAdr) { - PMethodRec recM = GetMethodInfo(classAdr, 'V', m); - if (recM) { - String name = recM->name; - if (name != "") { - int dotpos = name.Pos("."); - if (dotpos) - recN1->SetName(className + name.SubString(dotpos, name.Length())); - else - recN1->SetName(name); - - PInfoRec recN2 = GetInfoRec(recM->address); - recN1->kind = recN2->kind; - if (!recN1->procInfo->args && recN2->procInfo->args) { - recN1->procInfo->flags |= recN2->procInfo->flags & 7; - // Get Arguments - for (int n = 0; n < recN2->procInfo->args->Count; n++) { - PARGINFO argInfo2 = (PARGINFO)recN2->procInfo->args->Items[n]; - ARGINFO argInfo; - argInfo.Tag = argInfo2->Tag; - argInfo.Register = argInfo2->Register; - argInfo.Ndx = argInfo2->Ndx; - argInfo.Size = 4; - argInfo.Name = argInfo2->Name; - argInfo.TypeDef = TrimTypeName(argInfo2->TypeDef); - recN1->procInfo->AddArg(&argInfo); - } - } - recN->vmtInfo->AddMethod(false, 'V', m, procAdr, recN1->GetName()); - break; - } - } - classAdr = GetParentAdr(classAdr); - } - } - } -} - -// --------------------------------------------------------------------------- -PMethodRec __fastcall TFMain_11011981::GetMethodInfo(DWORD adr, char kind, int methodOfs) { - if (!IsValidCodeAdr(adr)) - return 0; - - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->id == methodOfs && recM->kind == kind) - return recM; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall ClearClassAdrMap() { - classAdrMap.clear(); -} - -// --------------------------------------------------------------------------- -DWORD __fastcall FindClassAdrByName(const String& AName) { - TClassAdrMap::const_iterator it = classAdrMap.find(AName); - if (it != classAdrMap.end()) - return it->second; - - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall AddClassAdr(DWORD Adr, const String& AName) { - classAdrMap[AName] = Adr; -} - -// --------------------------------------------------------------------------- -// Âîçâðàùàåò îáùèé ðîäèòåëüñêèé òèï äëÿ òèïîâ Name1, Name2 -String __fastcall TFMain_11011981::GetCommonType(String Name1, String Name2) { - if (SameText(Name1, Name2)) - return Name1; - - DWORD adr1 = GetClassAdr(Name1); - DWORD adr2 = GetClassAdr(Name2); - // Synonims - if (!adr1 || !adr2) { - // dword and ClassName -> ClassName - if (SameText(Name1, "Dword") && IsValidImageAdr(GetClassAdr(Name2))) - return Name2; - if (SameText(Name2, "Dword") && IsValidImageAdr(GetClassAdr(Name1))) - return Name1; - if (DelphiVersion >= 2009) { - // UString - UnicodeString - if ((SameText(Name1, "UString") && SameText(Name2, "UnicodeString")) || (SameText(Name1, "UnicodeString") && SameText(Name2, "UString"))) - return "UnicodeString"; - } - // String - AnsiString - if ((SameText(Name1, "String") && SameText(Name2, "AnsiString")) || (SameText(Name1, "AnsiString") && SameText(Name2, "String"))) - return "AnsiString"; - // Text - TTextRec - if ((SameText(Name1, "Text") && SameText(Name2, "TTextRec")) || (SameText(Name1, "TTextRec") && SameText(Name2, "Text"))) - return "TTextRec"; - return ""; - } - - int h1 = GetClassHeight(adr1); - int h2 = GetClassHeight(adr2); - - while (h1 != h2) { - if (h1 > h2) { - adr1 = GetParentAdr(adr1); - h1--; - } - else { - adr2 = GetParentAdr(adr2); - h2--; - } - } - - while (adr1 != adr2) { - adr1 = GetParentAdr(adr1); - adr2 = GetParentAdr(adr2); - } - - return GetClsName(adr1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormCreate(TObject *Sender) { - int n; - TMenuItem* mi; - LPCSTR buf[256]; - - if (!Disasm.Init()) { - ShowMessage("Cannot initialize Disasm"); - Application->Terminate(); - } - AppDir = ExtractFilePath(Application->ExeName); - if (AppDir[AppDir.Length()] != '\\') - AppDir += "\\"; - Application->HelpFile = AppDir + "idr.chm"; - IniFileRead(); - -#ifdef _DEBUG - BinsDir = AppDir + "..\\..\\..\\Bins\\"; -#else - BinsDir = AppDir + "Bins\\"; -#endif - - miDelphi2->Enabled = FileExists(BinsDir + "kb2.bin"); - miDelphi3->Enabled = FileExists(BinsDir + "kb3.bin"); - miDelphi4->Enabled = FileExists(BinsDir + "kb4.bin"); - miDelphi5->Enabled = FileExists(BinsDir + "kb5.bin"); - miDelphi6->Enabled = FileExists(BinsDir + "kb6.bin"); - miDelphi7->Enabled = FileExists(BinsDir + "kb7.bin"); - miDelphi2005->Enabled = FileExists(BinsDir + "kb2005.bin"); - miDelphi2006->Enabled = FileExists(BinsDir + "kb2006.bin"); - miDelphi2007->Enabled = FileExists(BinsDir + "kb2007.bin"); - miDelphi2009->Enabled = FileExists(BinsDir + "kb2009.bin"); - miDelphi2010->Enabled = FileExists(BinsDir + "kb2010.bin"); - miDelphiXE1->Enabled = FileExists(BinsDir + "kb2011.bin"); - miDelphiXE2->Enabled = FileExists(BinsDir + "kb2012.bin"); - miDelphiXE3->Enabled = FileExists(BinsDir + "kb2013.bin"); - miDelphiXE4->Enabled = FileExists(BinsDir + "kb2014.bin"); - - SegmentList = new TList; - ExpFuncList = new TList; - ImpFuncList = new TList; - ImpModuleList = new TStringList; - VmtList = new TList; - ResInfo = new TResourceInfo; - Units = new TList; - OwnTypeList = new TList; - UnitsSearchList = new TStringList; - RTTIsSearchList = new TStringList; - UnitItemsSearchList = new TStringList; - VMTsSearchList = new TStringList; - FormsSearchList = new TStringList; - StringsSearchList = new TStringList; - NamesSearchList = new TStringList; - - Init(); - - lbUnits->Canvas->Font->Assign(lbUnits->Font); - lbRTTIs->Canvas->Font->Assign(lbRTTIs->Font); - lbForms->Canvas->Font->Assign(lbForms->Font); - lbCode->Canvas->Font->Assign(lbCode->Font); - lbUnitItems->Canvas->Font->Assign(lbUnitItems->Font); - lbSourceCode->Canvas->Font->Assign(lbSourceCode->Font); - - lbCXrefs->Canvas->Font->Assign(lbCXrefs->Font); - lbCXrefs->Width = lbCXrefs->Canvas->TextWidth("T") * 14; - ShowCXrefs->Width = lbCXrefs->Width; - - lbSXrefs->Canvas->Font->Assign(lbSXrefs->Font); - lbSXrefs->Width = lbSXrefs->Canvas->TextWidth("T") * 14; - ShowSXrefs->Width = lbSXrefs->Width; - - lbNXrefs->Canvas->Font->Assign(lbNXrefs->Font); - lbNXrefs->Width = lbNXrefs->Canvas->TextWidth("T") * 14; - ShowNXrefs->Width = lbNXrefs->Width; - /* - //----Highlighting----------------------------------------------------------- - if (InitHighlight()) - { - lbSourceCode->Style = lbOwnerDrawFixed; - DelphiLbId = CreateHighlight(lbSourceCode->Handle, ID_DELPHI); - DelphiThemesCount = GetThemesCount(ID_DELPHI); - for (n = 0; n < DelphiThemesCount; n++) - { - mi = new TMenuItem(pmCode->Items); - GetThemeName(ID_DELPHI, (DWORD)n,(LPCSTR)buf, 256); - mi->Caption = String((char *)buf); - mi->Tag = n; - mi->OnClick = ChangeDelphiHighlightTheme; - miDelphiAppearance->Add(mi); - } - }; - //----Highlighting----------------------------------------------------------- - */ - ScaleForm(this); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormDestroy(TObject *Sender) { - CloseProject(); - - delete SegmentList; - delete ExpFuncList; - delete ImpFuncList; - delete ImpModuleList; - delete VmtList; - delete ResInfo; - delete OwnTypeList; - delete UnitsSearchList; - delete RTTIsSearchList; - delete UnitItemsSearchList; - delete VMTsSearchList; - delete FormsSearchList; - delete StringsSearchList; - delete NamesSearchList; - - for (int n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - delete recU->names; - } - delete Units; - /* - //----Highlighting----------------------------------------------------------- - if (DeleteHighlight) - { - DeleteHighlight(DelphiLbId); - } - FreeHighlight(); - //----Highlighting----------------------------------------------------------- - */ -} - -// --------------------------------------------------------------------------- -String __fastcall GetFilenameFromLink(String LinkName) { - String result = ""; - IPersistFile* ppf; - IShellLink* pshl; - WIN32_FIND_DATA wfd; - - // Initialize COM-library - CoInitialize(NULL); - // Create COM-object and get pointer to interface IPersistFile - CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IPersistFile, (void**)(&ppf)); - // Load Shortcut - wchar_t* temp = new WCHAR[MAX_PATH]; - StringToWideChar(LinkName, temp, MAX_PATH); - ppf->Load(temp, STGM_READ); - delete[]temp; - - // Get pointer to IShellLink - ppf->QueryInterface(IID_IShellLink, (void**)(&pshl)); - // Find Object shortcut points to - pshl->Resolve(0, SLR_ANY_MATCH | SLR_NO_UI); - // Get Object name - char* targetName = new char[MAX_PATH]; - pshl->GetPath(targetName, MAX_PATH, &wfd, 0); - result = String(targetName); - delete[]targetName; - - pshl->Release(); - ppf->Release(); - - CoFreeUnusedLibraries(); - CoUninitialize(); - - return result; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormShow(TObject *Sender) { - if (ParamCount() > 0) { - String FileName = ParamStr(1); - String fileExtension = ExtractFileExt(FileName); - // Shortcut - if (SameText(fileExtension, ".lnk")) { - FileName = GetFilenameFromLink(FileName); - } - - if (IsExe(FileName)) { - LoadDelphiFile1(FileName, DELHPI_VERSION_AUTO, true, true); - } - else if (IsIdp(FileName)) { - OpenProject(FileName); - } - else { - ShowMessage("File " + FileName + " is not executable or IDR project file"); - } - } -} - -// --------------------------------------------------------------------------- -/* - void __fastcall TFMain_11011981::ScanImports() - { - String name; - int *cnt = new int[KnowledgeBase.ModuleCount]; - //Ãîïðîáóåì ñêàíèðîâàòü èíòåðâàë àäðåñîâ áåçûìÿííûõ ìîäóëåé ïî èìåíàì èìïîðòèðóåìûõ ôóíêöèé - for (int m = 0; m < UnitsNum; m++) - { - PUnitRec recU = (PUnitRec)Units->Items[m]; - if (!recU->names->Count) - { - memset(cnt, 0, KnowledgeBase.ModuleCount*sizeof(int)); - - int fromPos = Adr2Pos(recU->fromAdr); - int toPos = Adr2Pos(recU->toAdr); - int totcnt = 0; - - for (int n = fromPos; n < toPos; n++) - { - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN && IsFlagSet(cfImport, n)) - { - name = ExtractProcName(recN->name); - KnowledgeBase.GetModuleIdsByProcName(name.c_str()); - for (int k = 0;;k++) - { - if (KnowledgeBase.Mods[k] == 0xFFFF) break; - cnt[KnowledgeBase.Mods[k]]++; - totcnt++; - } - } - } - - if (totcnt) - { - int num = 0; WORD id; - for (int k = 0; k < KnowledgeBase.ModuleCount; k++) - { - if (cnt[k] == totcnt) - { - id = k; - num++; - } - } - DWORD iniadr; PInfoRec recN; - //Åñëè âñå èìïîðòû íàøëèñü òîëüêî â îäíîì þíèòå, çíà÷èò ýòî îí è åñòü - if (num == 1) - { - name = KnowledgeBase.GetModuleName(id); - if (recU->names->IndexOf(name) == -1) - { - recU->kb = true; - SetUnitName(recU, name); - } - } - //Åñëè â íåñêîëüêèõ, ïîïðîáóåì ïîèñêàòü ïðîöåäóðû ïî cfProcStart (åñëè òàêîâûå èìåþòñÿ) - else - { - for (int k = 0; k < KnowledgeBase.ModuleCount; k++) - { - if (cnt[k] == totcnt) - { - id = k; - int FirstProcIdx, LastProcIdx; - if (!KnowledgeBase.GetProcIdxs(id, &FirstProcIdx, &LastProcIdx)) continue; - - for (int m = fromPos; m < toPos; m++) - { - if (IsFlagSet(cfProcStart, m) || !Flags[m]) - { - for (int Idx = FirstProcIdx; Idx <= LastProcIdx; Idx++) - { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) - { - MProcInfo *pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS); - //Ãàõîäèì ñîâïàäåíèå êîäà - if (KnowledgeBase.MatchCode(Code + m, pInfo) && StrapCheck(m, pInfo)) - { - name = KnowledgeBase.GetModuleName(id); - if (recU->names->IndexOf(name) == -1) - { - recU->kb = true; - SetUnitName(recU, name); - } - StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); - } - //as if (pInfo) delete pInfo; - } - } - } - } - } - } - } - } - } - } - delete[] cnt; - } - */ -// --------------------------------------------------------------------------- -String __fastcall TFMain_11011981::MakeComment(PPICODE Picode) { - bool vmt; - DWORD vmtAdr; - String comment = ""; - - if (Picode->Op == OP_CALL || Picode->Op == OP_COMMENT) { - comment = Picode->Name; - } - else { - PFIELDINFO fInfo = GetField(Picode->Name, Picode->Ofs.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - comment = Picode->Name + "."; - if (fInfo->Name == "") - comment += "?f" + Val2Str0(Picode->Ofs.Offset); - else - comment += fInfo->Name; - comment += ":"; - if (fInfo->Type == "") - comment += "?"; - else - comment += TrimTypeName(fInfo->Type); - - if (!vmt) - delete fInfo; - } - else if (Picode->Name != "") { - comment = Picode->Name + ".?f" + Val2Str0(Picode->Ofs.Offset) + ":?"; - } - } - return comment; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::RedrawCode() { - DWORD adr = CurProcAdr; - CurProcAdr = 0; - ShowCode(adr, lbCode->ItemIndex, lbCXrefs->ItemIndex, lbCode->TopIndex); -} - -// --------------------------------------------------------------------------- -// MXXXXXXXX textF -// M:<,>,= -// XXXXXXXX - adr -// F - flags -int __fastcall TFMain_11011981::AddAsmLine(DWORD Adr, String text, BYTE Flags) { - String _line = " " + Val2Str8(Adr) + " " + text + " "; - if (Flags & 1) - _line[1] = '>'; - if (Flags & 8) - _line[10] = '>'; - - int _len = _line.Length(); - _line[_len] = Flags; - - lbCode->Items->Add(_line); - return lbCode->Canvas->TextWidth(_line); -} - -// Argument SelectedIdx can be address (for selection) and index of list -void __fastcall TFMain_11011981::ShowCode(DWORD fromAdr, int SelectedIdx, int XrefIdx, int topIdx) { - BYTE op, flags; - int row = 0, wid, maxwid = 0, _pos, _idx, _ap; - TCanvas* canvas = lbCode->Canvas; - int num, instrLen, instrLen1, instrLen2, _procSize; - DWORD Adr, Adr1, Pos, lastMovAdr = 0; - int fromPos; - int curPos; - DWORD curAdr; - DWORD lastAdr = 0; - String line, line1; - PInfoRec recN; - DISINFO DisInfo, DisInfo1; - char disLine[100]; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return; - - bool selectByAdr = (IsValidImageAdr(SelectedIdx) == true); - // If procedure is the same then move selection and not update Xrefs - if (fromAdr == CurProcAdr) { - if (selectByAdr) { - for (int i = 1; i < lbCode->Items->Count; i++) { - line = lbCode->Items->Strings[i]; - sscanf(AnsiString(line).c_str() + 1, "%lX", &Adr); - if (Adr >= SelectedIdx) { - if (Adr == SelectedIdx) { - lbCode->ItemIndex = i; - break; - } - else { - lbCode->ItemIndex = i - 1; - break; - } - } - } - } - else - lbCode->ItemIndex = SelectedIdx; - - pcWorkArea->ActivePage = tsCodeView; - return; - } - if (!AnalyzeThread) // Clear all Items (used in highlighting) - { - // AnalyzeProc1(fromAdr, 0, 0, 0, false);//!!! - AnalyzeProc2(fromAdr, false, false); - } - - CurProcAdr = fromAdr; - CurProcSize = 0; - lbCode->Clear(); - lbCode->Items->BeginUpdate(); - - recN = GetInfoRec(fromAdr); - - int outRows = MAX_DISASSEMBLE; - if (IsFlagSet(cfImport, fromPos)) - outRows = 2; - - line = " "; - if (fromAdr == EP) { - line += "EntryPoint"; - } - else { - String moduleName = ""; - String procName = ""; - - PUnitRec recU = GetUnit(fromAdr); - if (recU) { - moduleName = GetUnitName(recU); - if (fromAdr == recU->iniadr) - procName = "Initialization"; - else if (fromAdr == recU->finadr) - procName = "Finalization"; - } - if (recN && procName == "") - procName = recN->MakeMapName(fromAdr); - - if (moduleName != "") - line += moduleName + "." + procName; - else - line += procName; - } - lProcName->Caption = line; - lbCode->Items->Add(line); - row++; - - _procSize = GetProcSize(fromAdr); - curPos = fromPos; - curAdr = fromAdr; - - while (row < outRows) { - // End of procedure - if (curAdr != fromAdr && _procSize && curAdr - fromAdr >= _procSize) - break; - // Loc? - flags = ' '; - if (curAdr != CurProcAdr && IsFlagSet(cfLoc, curPos)) - flags |= 1; - if (IsFlagSet(cfFrame | cfSkip, curPos)) - flags |= 2; - if (IsFlagSet(cfLoop, curPos)) - flags |= 4; - - // If exception table, output it - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - wid = AddAsmLine(curAdr, "dd " + String(num), flags); - row++; - if (wid > maxwid) - maxwid = wid; - - curPos += 4; - curAdr += 4; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Adr = *((DWORD*)(Code + curPos)); - line1 = "dd " + Val2Str8(Adr); - // Name of Exception - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) - line1 += ";" + recN->GetName(); - } - wid = AddAsmLine(curAdr, line1, flags); - row++; - if (wid > maxwid) - maxwid = wid; - - // dd offset ExceptionProc - curPos += 4; - curAdr += 4; - Adr = *((DWORD*)(Code + curPos)); - wid = AddAsmLine(curAdr, "dd " + Val2Str8(Adr), flags); - row++; - if (wid > maxwid) - maxwid = wid; - - curPos += 4; - curAdr += 4; - } - continue; - } - - BYTE b1 = Code[curPos]; - BYTE b2 = Code[curPos + 1]; - if (!b1 && !b2 && !lastAdr) - break; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, disLine); - if (!instrLen) { - wid = AddAsmLine(curAdr, "???", 0x22); - row++; - if (wid > maxwid) - maxwid = wid; - curPos++; - curAdr++; - continue; - } - op = Disasm.GetOp(DisInfo.Mnem); - - // Check inside instruction Fixup or ThreadVar - bool NameInside = false; - DWORD NameInsideAdr; - for (int k = 1; k < instrLen; k++) { - if (Infos[curPos + k]) { - NameInside = true; - NameInsideAdr = curAdr + k; - break; - } - } - - line = String(disLine); - - if (curAdr >= lastAdr) - lastAdr = 0; - - // Proc end - if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) { - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - break; - } - - if (op == OP_MOV) - lastMovAdr = DisInfo.Offset; - - if (b1 == 0xEB || // short relative abs jmp or cond jmp - (b1 >= 0x70 && b1 <= 0x7F) || (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - if (op == OP_JMP) { - _ap = Adr2Pos(Adr); - recN = GetInfoRec(Adr); - if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) { - line = "jmp " + recN->GetName(); - } - } - flags |= 8; - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (b1 == 0xE9) // relative abs jmp or cond jmp - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - _ap = Adr2Pos(Adr); - recN = GetInfoRec(Adr); - if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) { - line = "jmp " + recN->GetName(); - } - flags |= 8; - if (!recN && Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (DisInfo.Call) // call sub_XXXXXXXX - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) { - line = "call " + recN->GetName(); - // Found @Halt0 - exit - if (recN->SameName("@Halt0") && fromAdr == EP && !lastAdr) { - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - break; - } - } - } - recN = GetInfoRec(curAdr); - if (recN && recN->picode) - line += ";" + MakeComment(recN->picode); - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) - // near absolute indirect jmp (Case) - { - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - if (!IsValidCodeAdr(DisInfo.Offset)) - break; - /* - //First instruction - if (curAdr == fromAdr) break; - */ - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Table address - last 4 bytes of instruction - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Analyze address range to find table cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // If exist cTblAdr, skip this table - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - for (int k = 0; k < CNum; k++) { - BYTE db = Code[Pos]; - CTab[k] = db; - wid = AddAsmLine(Adr, "db " + String(db), 0x22); - row++; - if (wid > maxwid) - maxwid = wid; - Pos++; - Adr++; - } - } - // Check transitions by negative register values (in Delphi 2009) - // bool neg = false; - // Adr1 = *((DWORD*)(Code + Pos - 4)); - // if (IsValidCodeAdr(Adr1) && IsFlagSet(cfLoc, Adr2Pos(Adr1))) neg = true; - - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - - // Add row to assembler listing - wid = AddAsmLine(Adr, "dd " + Val2Str8(Adr1), 0x22); - row++; - if (wid > maxwid) - maxwid = wid; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - // ---------------------------------- - // PosTry: xor reg, reg - // push ebp - // push offset @1 - // push fs:[reg] - // mov fs:[reg], esp - // ... - // @2: ... - // At @1 various variants: - // ---------------------------------- - // @1: jmp @HandleFinally - // jmp @2 - // ---------------------------------- - // @1: jmp @HandleAnyException - // call DoneExcept - // ---------------------------------- - // @1: jmp HandleOnException - // dd num - // Äàëåå òàáëèöà èç num çàïèñåé âèäà - // dd offset ExceptionInfo - // dd offset ExceptionProc - // ---------------------------------- - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN = GetInfoRec(DisInfo.Immediate); - if (recN) { - if (recN->SameName("@HandleFinally")) { - // jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - /* - //@2 - Adr1 = DisInfo.Immediate - 4; - Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); - if (IsValidCodeAdr(Adr) && Adr > lastAdr) lastAdr = Adr; - */ - } - else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // Set flag cfETable to correct output data - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Pos += 4; - // dd offset ExceptionProc - Pos += 4; - } - } - } - } - } - } - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - // Name inside instruction (Fixip, ThreadVar) - String namei = "", comment = "", name, pname, type, ptype; - if (NameInside) { - recN = GetInfoRec(NameInsideAdr); - if (recN && recN->HasName()) { - namei += recN->GetName(); - if (recN->type != "") - namei += ":" + recN->type; - } - } - // comment - recN = GetInfoRec(curAdr); - if (recN && recN->picode) - comment = MakeComment(recN->picode); - - DWORD targetAdr = 0; - if (IsValidImageAdr(DisInfo.Immediate)) { - if (!IsValidImageAdr(DisInfo.Offset)) - targetAdr = DisInfo.Immediate; - } - else if (IsValidImageAdr(DisInfo.Offset)) - targetAdr = DisInfo.Offset; - - if (targetAdr) { - name = pname = type = ptype = ""; - _pos = Adr2Pos(targetAdr); - if (_pos >= 0) { - recN = GetInfoRec(targetAdr); - if (recN) { - if (recN->kind == ikResString) { - name = recN->GetName() + ":PResStringRec"; - } - else { - if (recN->HasName()) { - name = recN->GetName(); - if (recN->type != "") - type = recN->type; - } - else if (IsFlagSet(cfProcStart, _pos)) - name = GetDefaultProcName(targetAdr); - } - } - // For Delphi2 pointers to VMT are distinct - else if (DelphiVersion == 2) { - recN = GetInfoRec(targetAdr + VmtSelfPtr); - if (recN && recN->kind == ikVMT && recN->HasName()) { - name = recN->GetName(); - } - } - Adr = *((DWORD*)(Code + _pos)); - if (IsValidImageAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN) { - if (recN->HasName()) { - pname = recN->GetName(); - ptype = recN->type; - } - else if (IsFlagSet(cfProcStart, _pos)) - pname = GetDefaultProcName(Adr); - } - } - } - else { - _idx = BSSInfos->IndexOf(Val2Str8(targetAdr)); - if (_idx != -1) { - recN = (PInfoRec)BSSInfos->Objects[_idx]; - name = recN->GetName(); - type = recN->type; - } - } - } - if (SameText(comment, name)) - name = ""; - if (pname != "") { - if (comment != "") - comment += " "; - comment += "^" + pname; - if (ptype != "") - comment += ":" + ptype; - } - else if (name != "") { - if (comment != "") - comment += " "; - comment += name; - if (type != "") - comment += ":" + type; - } - - if (comment != "" || namei != "") { - line += ";"; - if (comment != "") - line += comment; - if (namei != "") - line += "{" + namei + "}"; - } - if (line.Length() > MAXLEN) - line = line.SubString(1, MAXLEN) + "..."; - wid = AddAsmLine(curAdr, line, flags); - row++; - if (wid > maxwid) - maxwid = wid; - curPos += instrLen; - curAdr += instrLen; - } - - CurProcSize = (curAdr + instrLen) - CurProcAdr; - - if (selectByAdr) { - for (int i = 1; i < lbCode->Items->Count; i++) { - line = lbCode->Items->Strings[i]; - sscanf(AnsiString(line).c_str() + 1, "%lX", &Adr); - if (Adr >= SelectedIdx) { - if (Adr == SelectedIdx) { - lbCode->ItemIndex = i; - break; - } - else { - lbCode->ItemIndex = i - 1; - break; - } - } - } - } - else - lbCode->ItemIndex = SelectedIdx; - - if (topIdx != -1) - lbCode->TopIndex = topIdx; - lbCode->ItemHeight = lbCode->Canvas->TextHeight("T"); - lbCode->ScrollWidth = maxwid + 2; - lbCode->Items->EndUpdate(); - - ShowCodeXrefs(CurProcAdr, XrefIdx); - pcWorkArea->ActivePage = tsCodeView; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AnalyzeMethodTable(int Pass, DWORD Adr, const bool* Terminated) { - BYTE sLen, paramFlags, paramCount, cc; - WORD skipNext, dw, parOfs; - int procPos; - DWORD procAdr, paramType, resultType; - PInfoRec recN; - String paramName, methodName; - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD methodAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr) + VmtMethodTable)); - - if (!methodAdr) - return; - - String className = GetClsName(Adr); - int pos = Adr2Pos(methodAdr); - WORD count = *((WORD*)(Code + pos)); - pos += 2; - - for (int n = 0; n < count && !*Terminated; n++) { - skipNext = *((WORD*)(Code + pos)); - procAdr = *((DWORD*)(Code + pos + 2)); - procPos = Adr2Pos(procAdr); - sLen = Code[pos + 6]; - methodName = String((char*)(Code + pos + 7), sLen); - - AnalyzeProc(Pass, procAdr); - - if (Pass == 1) { - recN = GetInfoRec(procAdr); - if (recN && recN->kind != ikConstructor && recN->kind != ikDestructor && recN->kind != ikClassRef) { - recN->SetName(className + "." + methodName); - recN->kind = ikProc; - recN->AddXref('D', Adr, 0); - recN->procInfo->AddArg(0x21, 0, 4, "Self", className); - } - } - pos += skipNext; - } - if (DelphiVersion >= 2010) { - WORD exCount = *((WORD*)(Code + pos)); - pos += 2; - for (int n = 0; n < exCount && !*Terminated; n++) { - DWORD methodEntry = *((DWORD*)(Code + pos)); - pos += 4; - WORD flags = *((WORD*)(Code + pos)); - pos += 2; - WORD vIndex = *((WORD*)(Code + pos)); - pos += 2; - int spos = pos; - pos = Adr2Pos(methodEntry); - // Length - skipNext = *((WORD*)(Code + pos)); - pos += 2; - procAdr = *((DWORD*)(Code + pos)); - pos += 4; - procPos = Adr2Pos(procAdr); - sLen = Code[pos]; - methodName = String((char*)(Code + pos + 1), sLen); - pos += sLen + 1; - - if (procAdr == Adr) - continue; - - recN = GetInfoRec(procAdr); - // IMHO it means that methods are pure virtual calls and must be readed in child classes - if (recN && recN->kind == ikVMT) { - pos = spos; - continue; - } - AnalyzeProc(Pass, procAdr); - recN = GetInfoRec(procAdr); - - if (Pass == 1) { - if (recN && recN->procInfo && recN->kind != ikConstructor && recN->kind != ikDestructor) // recN->kind != ikClassRef - { - recN->SetName(className + "." + methodName); - recN->kind = ikProc; - recN->AddXref('D', Adr, 0); - recN->procInfo->AddArg(0x21, 0, 4, "Self", className); - } - } - if (pos - Adr2Pos(methodEntry) < skipNext) { - // Version - pos++; - cc = Code[pos]; - pos++; - resultType = *((DWORD*)(Code + pos)); - pos += 4; - // ParOff - pos += 2; - if (Pass == 1) { - if (recN && recN->procInfo && recN->kind != ikConstructor && recN->kind != ikDestructor) // recN->kind != ikClassRef) - { - if (resultType) { - recN->kind = ikFunc; - recN->type = GetTypeName(resultType); - } - if (cc != 0xFF) - recN->procInfo->flags |= cc; - } - } - paramCount = Code[pos]; - pos++; - if (Pass == 1) { - if (recN && recN->procInfo) { - recN->procInfo->DeleteArgs(); - if (!paramCount) - recN->procInfo->AddArg(0x21, 0, 4, "Self", className); - } - } - for (int m = 0; m < paramCount && !*Terminated; m++) { - paramFlags = Code[pos]; - pos++; - paramType = *((DWORD*)(Code + pos)); - pos += 4; - // ParOff - parOfs = *((WORD*)(Code + pos)); - pos += 2; - sLen = Code[pos]; - paramName = String((char*)(Code + pos + 1), sLen); - pos += sLen + 1; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - if (paramFlags & 0x40) - continue; // Result - if (Pass == 1) { - if (recN && recN->procInfo) // recN->kind != ikClassRef) - { - Byte tag = 0x21; - if (paramFlags & 1) - tag = 0x22; - recN->procInfo->AddArg(tag, parOfs, 4, paramName, GetTypeName(paramType)); - } - } - } - } - else { - cc = 0xFF; - paramCount = 0; - } - pos = spos; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AnalyzeDynamicTable(int Pass, DWORD Adr, const bool* Terminated) { - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD DynamicAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr) + VmtDynamicTable)); - if (!DynamicAdr) - return; - - String clsName = GetClsName(Adr); - DWORD pos = Adr2Pos(DynamicAdr); - WORD Num = *((WORD*)(Code + pos)); - pos += 2; - DWORD post = pos + 2 * Num; - - for (int i = 0; i < Num && !*Terminated; i++, post += 4) { - // WORD Msg - pos += 2; - DWORD procAdr = *((DWORD*)(Code + post)); - int procPos = Adr2Pos(procAdr); - if (!procPos) - continue; // Something wrong! - bool skip = (*(Code + procPos) == 0 && *(Code + procPos + 1) == 0); - if (!skip) - AnalyzeProc(Pass, procAdr); - - if (Pass == 1 && !skip) { - PInfoRec recN = GetInfoRec(procAdr); - if (recN) { - recN->kind = ikProc; - recN->procInfo->flags |= PF_DYNAMIC; - recN->AddXref('D', Adr, 0); - recN->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AnalyzeVirtualTable(int Pass, DWORD Adr, const bool* Terminated) { - DWORD parentAdr = GetParentAdr(Adr); - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD stopAt = GetStopAt(vmtAdr); - if (vmtAdr == stopAt) - return; - - int pos = Adr2Pos(vmtAdr) + VmtParent + 4; - for (int n = VmtParent + 4; !*Terminated; n += 4, pos += 4) { - if (Pos2Adr(pos) == stopAt) - break; - DWORD procAdr = *((DWORD*)(Code + pos)); - int procPos = Adr2Pos(procAdr); - bool skip = (*(Code + procPos) == 0 && *(Code + procPos + 1) == 0); - if (!skip) - AnalyzeProc(Pass, procAdr); - PInfoRec recN = GetInfoRec(procAdr); - - if (recN) { - if (Pass == 1 && !skip) { - recN->procInfo->flags |= PF_VIRTUAL; - recN->AddXref('D', Adr, 0); - } - - DWORD pAdr = parentAdr; - while (pAdr && !*Terminated) { - PInfoRec recN1 = GetInfoRec(pAdr); - // Look at parent class methods - if (recN1 && recN1->vmtInfo && recN1->vmtInfo->methods) { - for (int m = 0; m < recN1->vmtInfo->methods->Count; m++) { - PMethodRec recM = (PMethodRec)recN1->vmtInfo->methods->Items[m]; - if (recM->abstract && recM->kind == 'V' && recM->id == n && recM->name == "") { - String procName = recN->GetName(); - if (procName != "" && !SameText(procName, "@AbstractError")) { - recM->name = GetClsName(pAdr) + "." + ExtractProcName(procName); - } - break; - } - } - } - pAdr = GetParentAdr(pAdr); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AnalyzeProc(int pass, DWORD procAdr) { - switch (pass) { - case 0: - AnalyzeProcInitial(procAdr); - break; - case 1: - AnalyzeProc1(procAdr, 0, 0, 0, false); - break; - case 2: - AnalyzeProc2(procAdr, true, true); - break; - } -} - -// --------------------------------------------------------------------------- -// Scan proc calls -DWORD __fastcall TFMain_11011981::AnalyzeProcInitial(DWORD fromAdr) { - BYTE op, b1, b2; - int num, instrLen, instrLen1, instrLen2, _procSize; - int fromPos; - int curPos; - DWORD curAdr; - DWORD lastAdr = 0; - DWORD Adr, Adr1, Pos, lastMovAdr = 0; - PInfoRec recN; - DISINFO DisInfo, DisInfo1; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return 0; - if (IsFlagSet(cfPass0, fromPos)) - return 0; - if (IsFlagSet(cfEmbedded, fromPos)) - return 0; - if (IsFlagSet(cfExport, fromPos)) - return 0; - - // b1 = Code[fromPos]; - // b2 = Code[fromPos + 1]; - // if (!b1 && !b2) return 0; - - SetFlag(cfProcStart | cfPass0, fromPos); - - // Don't analyze imports - if (IsFlagSet(cfImport, fromPos)) - return 0; - - _procSize = GetProcSize(fromAdr); - curPos = fromPos; - curAdr = fromAdr; - - while (1) { - if (curAdr >= CodeBase + TotalSize) - break; - // For example, cfProcEnd can be set for interface procs - if (_procSize && curAdr - fromAdr >= _procSize) - break; - // Skip exception table - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - curPos += 4 + 8 * num; - curAdr += 4 + 8 * num; - continue; - } - - b1 = Code[curPos]; - b2 = Code[curPos + 1]; - if (!b1 && !b2 && !lastAdr) - break; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) break; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - - op = Disasm.GetOp(DisInfo.Mnem); - // Code - SetFlags(cfCode, curPos, instrLen); - // Instruction begin - SetFlag(cfInstruction, curPos); - - if (curAdr >= lastAdr) - lastAdr = 0; - - // End of procedure - if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) - break; - - if (op == OP_MOV) - lastMovAdr = DisInfo.Offset; - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) - // near absolute indirect jmp (Case) - { - if (!IsValidCodeAdr(DisInfo.Offset)) - break; - /* - //First instruction - if (curAdr == fromAdr) break; - */ - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Table address - last 4 bytes of instruction - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Scan gap to find table cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // If exists cTblAdr skip it - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - Pos += CNum; - Adr += CNum; - } - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // Check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - int delta = Pos - NPos; - if (delta >= 0 && delta < MAX_DISASSEMBLE) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN = GetInfoRec(DisInfo.Immediate); - if (recN) { - if (recN->SameName("@HandleFinally")) { - // jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - /* - //@2 - Adr1 = DisInfo.Immediate - 4; - Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); - if (Adr > lastAdr) lastAdr = Adr; - */ - } - else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // Set flag cfETable to correctly output data - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Pos += 4; - // dd offset ExceptionProc - Pos += 4; - } - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - } - - if (DisInfo.Call) // call sub_XXXXXXXX - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - // If @Halt0 - end of procedure - if (recN && recN->SameName("@Halt0")) { - if (fromAdr == EP && !lastAdr) - break; - } - AnalyzeProcInitial(Adr); - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (op == OP_JMP) { - if (curAdr == fromAdr) - return 0; - if (DisInfo.OpType[0] == otMEM) { - if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) - return 0; - } - if (DisInfo.OpType[0] == otIMM) { - Adr = DisInfo.Immediate; - if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) - return 0; - if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) - return 0; - if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) - return Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (DisInfo.Conditional) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - curPos += instrLen; - curAdr += instrLen; - } -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::CodeGetTargetAdr(String Line, DWORD* trgAdr) { - char *s, *p, c; - int n, wid, instrlen; - DWORD adr, targetAdr; - TPoint cursorPos; - TCanvas* canvas = lbCode->Canvas; - DISINFO DisInfo; - - *trgAdr = 0; - s = AnsiString(Line).c_str() + 1; - - // If db - no address - if (strstr(s, " db ")) - return 0; - // If dd - address - p = strstr(s, " dd "); - if (p) - sscanf(p + 4, "%lX", &targetAdr); - - if (!IsValidImageAdr(targetAdr)) { - sscanf(s, "%lX", &adr); - instrlen = Disasm.Disassemble(Code + Adr2Pos(adr), (__int64)adr, &DisInfo, 0); - if (!instrlen) - return 0; - - if (IsValidImageAdr(DisInfo.Immediate)) { - if (!IsValidImageAdr(DisInfo.Offset)) - targetAdr = DisInfo.Immediate; - } - else if (IsValidImageAdr(DisInfo.Offset)) - targetAdr = DisInfo.Offset; - } - if (!IsValidImageAdr(targetAdr)) { - GetCursorPos(&cursorPos); - cursorPos = lbCode->ScreenToClient(cursorPos); - for (n = 0, wid = 0; n < strlen(s); n++) { - int cwid = canvas->TextWidth(s[n]); - if (wid >= cursorPos.x) { - while (n >= 0) { - c = s[n]; - if (c == ' ' || c == ',' || c == '[' || c == '+') { - sscanf(s + n + 1, "%lX", &targetAdr); - break; - } - n--; - } - break; - } - wid += cwid; - } - } - if (IsValidImageAdr(targetAdr)) - * trgAdr = targetAdr; - return DisInfo.OpSize; -} - -// --------------------------------------------------------------------------- -// May be Plugin!!! -String __fastcall sub_004AFB28(BYTE* AStr) { - Integer _n, _num; - Byte _b, _b1, _b2, _m; - String _result; - - if (AStr[0] == 0x7B) { - _m = 1; - _n = 2; - _b1 = AStr[1]; - _num = _b1 ^ 0xA1; - _result = ""; - if (_num > 0) { - do { - _b2 = AStr[_n]; - _b1 = (3 * _m + _b1) ^ _b2; - _b = _b1; - _b1 = _b2; - _m = _m + 1; - _n = _n + 1; - _num = _num - 1; - _b2 = AStr[_n]; - _b1 = (3 * _m + _b1) ^ _b2; - _b = _b | _b1; - if (_b) { - _result += Char(_b); - } - _b1 = _b2; - _m = _m + 1; - _n = _n + 1; - _num = _num - 1; - } - while (_num > 0); - } - } - else { - _result = "!"; - } - return _result; -} - -// --------------------------------------------------------------------------- -void __fastcall sub_004AF80C(BYTE* AStr1, BYTE* AStr2) { - BYTE* _p; - BYTE _b, _n; - int _num; - - _n = *(AStr1 + 7); - _p = AStr1 + 2 + 8; - _num = AStr2 - _p; - if (_num > 0) { - do { - _b = *_p; - _b = ((0xFF - _b + 12) ^ 0xC2) - 3 * _n - 0x62; - *_p = _b; - _p++; - _n++; - _num--; - } - while (_num > 0); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbCodeDblClick(TObject *Sender) { - int pos, bytes, size; - DWORD adr, adr1, targetAdr; - PInfoRec recN; - PROCHISTORYREC rec; - String text; - - if (lbCode->ItemIndex <= 0) - return; - - text = lbCode->Items->Strings[lbCode->ItemIndex]; - size = CodeGetTargetAdr(text, &targetAdr); - - if (IsValidImageAdr(targetAdr)) { - pos = Adr2Pos(targetAdr); - if (pos == -2) - return; - if (pos == -1) { - ShowMessage("BSS"); - return; - } - if (IsFlagSet(cfImport, pos)) { - ShowMessage("Import"); - return; - } - // RTTI - if (IsFlagSet(cfRTTI, pos)) { - FTypeInfo_11011981->ShowRTTI(targetAdr); - return; - } - // if start of procedure, show it - if (IsFlagSet(cfProcStart, pos)) { - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(Pos2Adr(pos), targetAdr, -1, -1); - CodeHistoryPush(&rec); - return; - } - - recN = GetInfoRec(targetAdr); - if (recN) { - if (recN->kind == ikVMT && tsClassView->TabVisible) { - ShowClassViewer(targetAdr); - return; - } - if (recN->kind == ikResString) { - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->Caption = "ResString context"; - FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); - FStringInfo_11011981->ShowModal(); - return; - } - if (recN->HasName()) { - WORD *uses = KnowledgeBase.GetTypeUses(AnsiString(recN->GetName()).c_str()); - int idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(recN->GetName()).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - MTypeInfo tInfo; - if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS | INFO_DUMP, &tInfo)) { - FTypeInfo_11011981->ShowKbInfo(&tInfo); - // as delete tInfo; - return; - } - } - } - } - // may be -> - adr = *((DWORD*)(Code + pos)); - if (IsValidImageAdr(adr)) { - recN = GetInfoRec(adr); - if (recN) { - if (recN->kind == ikResString) { - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->Caption = "ResString context"; - FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); - FStringInfo_11011981->ShowModal(); - return; - } - } - } - - // if in current proc - if (CurProcAdr <= targetAdr && targetAdr < CurProcAdr + CurProcSize) { - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(CurProcAdr, targetAdr, lbCXrefs->ItemIndex, -1); - CodeHistoryPush(&rec); - return; - } - // Else show explorer - FExplorer_11011981->tsCode->TabVisible = true; - FExplorer_11011981->ShowCode(targetAdr, 1024); - FExplorer_11011981->tsData->TabVisible = true; - FExplorer_11011981->ShowData(targetAdr, 1024); - FExplorer_11011981->tsString->TabVisible = true; - FExplorer_11011981->ShowString(targetAdr, 1024); - FExplorer_11011981->tsText->TabVisible = false; - FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsData; - FExplorer_11011981->WAlign = -4; - - FExplorer_11011981->btnDefCode->Enabled = true; - if (IsFlagSet(cfCode, pos)) - FExplorer_11011981->btnDefCode->Enabled = false; - FExplorer_11011981->btnUndefCode->Enabled = false; - if (IsFlagSet(cfCode | cfData, pos)) - FExplorer_11011981->btnUndefCode->Enabled = true; - - if (FExplorer_11011981->ShowModal() == mrOk) { - if (FExplorer_11011981->DefineAs == DEFINE_AS_CODE) { - // Delete any information at this address - recN = GetInfoRec(Pos2Adr(pos)); - if (recN) - delete recN; - // Create new info about proc - recN = new InfoRec(pos, ikRefine); - - // AnalyzeProcInitial(targetAdr); - AnalyzeProc1(targetAdr, 0, 0, 0, false); - AnalyzeProc2(targetAdr, true, true); - AnalyzeArguments(targetAdr); - AnalyzeProc2(targetAdr, true, true); - - if (!ContainsUnexplored(GetUnit(targetAdr))) - ShowUnits(true); - ShowUnitItems(GetUnit(targetAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(targetAdr, 0, -1, -1); - CodeHistoryPush(&rec); - ProjectModified = true; - } - } - } - // Try picode - else { - sscanf(AnsiString(text).c_str() + 2, "%lX", &adr); - recN = GetInfoRec(adr); - if (recN && recN->picode && IsValidCodeAdr(recN->picode->Ofs.Address)) { - pos = Adr2Pos(recN->picode->Ofs.Address); - if (IsFlagSet(cfProcStart, pos)) { - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(Pos2Adr(pos), targetAdr, -1, -1); - CodeHistoryPush(&rec); - return; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::bEPClick(TObject *Sender) { - PROCHISTORYREC rec; - - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(EP, 0, -1, -1); - CodeHistoryPush(&rec); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::GoToAddress() { - int pos; - DWORD gotoAdr; - String sAdr; - PROCHISTORYREC rec; - - // if (lbCode->ItemIndex <= 0) return; - - sAdr = InputDialogExec("Enter Address", "Address:", ""); - if (sAdr != "") { - sscanf(AnsiString(sAdr).c_str(), "%lX", &gotoAdr); - if (IsValidCodeAdr(gotoAdr)) { - pos = Adr2Pos(gotoAdr); - // Åñëè èìïîðò - íè÷åãî íå îòîáðàæàåì - if (IsFlagSet(cfImport, pos)) - return; - // Èùåì, êóäà ïîïàäàåò àäðåñ - while (pos >= 0) { - // Ãàøëè íà÷àëî ïðîöåäóðû - if (IsFlagSet(cfProcStart, pos)) { - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(Pos2Adr(pos), gotoAdr, -1, -1); - CodeHistoryPush(&rec); - break; - } - // Ãàøëè íà÷àëî òèïà - if (IsFlagSet(cfRTTI, pos)) { - FTypeInfo_11011981->ShowRTTI(Pos2Adr(pos)); - break; - } - pos--; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miGoToClick(TObject *Sender) { - GoToAddress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExploreAdrClick(TObject *Sender) { - int size; - DWORD viewAdr; - String text = "", sAdr; - PInfoRec recN; - - if (lbCode->ItemIndex <= 0) - return; - - size = CodeGetTargetAdr(lbCode->Items->Strings[lbCode->ItemIndex], &viewAdr); - if (viewAdr) - text = Val2Str8(viewAdr); - sAdr = InputDialogExec("Enter Address", "Address:", text); - if (sAdr != "") { - sscanf(AnsiString(sAdr).c_str(), "%lX", &viewAdr); - if (IsValidImageAdr(viewAdr)) { - int pos = Adr2Pos(viewAdr); - if (pos == -2) - return; - if (pos == -1) { - ShowMessage("BSS"); - return; - } - FExplorer_11011981->tsCode->TabVisible = true; - FExplorer_11011981->ShowCode(viewAdr, 1024); - FExplorer_11011981->tsData->TabVisible = true; - FExplorer_11011981->ShowData(viewAdr, 1024); - FExplorer_11011981->tsString->TabVisible = true; - FExplorer_11011981->ShowString(viewAdr, 1024); - FExplorer_11011981->tsText->TabVisible = false; - FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsCode; - FExplorer_11011981->WAlign = -4; - - FExplorer_11011981->btnDefCode->Enabled = true; - if (IsFlagSet(cfCode, pos)) - FExplorer_11011981->btnDefCode->Enabled = false; - FExplorer_11011981->btnUndefCode->Enabled = false; - if (IsFlagSet(cfCode | cfData, pos)) - FExplorer_11011981->btnUndefCode->Enabled = true; - - if (FExplorer_11011981->ShowModal() == mrOk) { - switch (FExplorer_11011981->DefineAs) { - case DEFINE_AS_CODE: - // Delete any information at this address - recN = GetInfoRec(viewAdr); - if (recN) - delete recN; - // Create new info about proc - recN = new InfoRec(pos, ikRefine); - - // AnalyzeProcInitial(viewAdr); - AnalyzeProc1(viewAdr, 0, 0, 0, false); - AnalyzeProc2(viewAdr, true, true); - AnalyzeArguments(viewAdr); - AnalyzeProc2(viewAdr, true, true); - - if (!ContainsUnexplored(GetUnit(viewAdr))) - ShowUnits(true); - ShowUnitItems(GetUnit(viewAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - ShowCode(viewAdr, 0, -1, -1); - break; - case DEFINE_AS_STRING: - break; - } - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::NamePosition() { - int pos, _idx, size; - DWORD adr, nameAdr; - PInfoRec recN; - String line, text = "", sNameType, newName, newType; - - if (lbCode->ItemIndex >= 1) { - line = lbCode->Items->Strings[lbCode->ItemIndex]; - size = CodeGetTargetAdr(line, &nameAdr); - } - - if (IsValidImageAdr(nameAdr)) { - pos = Adr2Pos(nameAdr); - recN = GetInfoRec(nameAdr); - // VMT - if (recN && recN->kind == ikVMT) - return; - - // if (size == 4) - // { - adr = *((DWORD*)(Code + pos)); - if (IsValidImageAdr(adr)) - nameAdr = adr; - // } - } - else { - nameAdr = CurProcAdr; - } - - pos = Adr2Pos(nameAdr); - recN = GetInfoRec(nameAdr); - if (recN && recN->HasName()) { - text = recN->GetName(); - if (recN->type != "") - text = recN->GetName() + ":" + recN->type; - } - - sNameType = InputDialogExec("Enter Name:Type (at " + Val2Str8(nameAdr) + ")", "Name:Type", text); - if (sNameType != "") { - if (sNameType.Pos(":")) { - newName = ExtractName(sNameType).Trim(); - newType = ExtractType(sNameType).Trim(); - } - else { - newName = sNameType; - newType = ""; - } - - if (newName == "") - return; - - // If call - if (pos >= 0 && IsFlagSet(cfProcStart, pos)) { - if (!recN) - recN = new InfoRec(pos, ikRefine); - recN->kind = ikProc; - recN->SetName(newName); - if (newType != "") { - recN->kind = ikFunc; - recN->type = newType; - } - } - else { - if (pos >= 0) { - // Address points to Data - if (!recN) - recN = new InfoRec(pos, ikUnknown); - recN->SetName(newName); - if (newType != "") - recN->type = newType; - } - else { - _idx = BSSInfos->IndexOf(Val2Str8(nameAdr)); - if (_idx != -1) { - recN = (PInfoRec)BSSInfos->Objects[_idx]; - recN->SetName(newName); - recN->type = newType; - } - else - recN = AddToBSSInfos(nameAdr, newName, newType); - } - } - - RedrawCode(); - ShowUnitItems(GetUnit(CurUnitAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - ProjectModified = true; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miNameClick(TObject *Sender) { - NamePosition(); -} - -// --------------------------------------------------------------------------- -TTreeNode* __fastcall TFMain_11011981::GetNodeByName(String AName) { - for (int n = 0; n < tvClassesFull->Items->Count; n++) { - TTreeNode *node = tvClassesFull->Items->Item[n]; - String text = node->Text; - if (AName[1] != ' ') { - if (text[1] != '<' && text[1] == AName[1] && text[2] == AName[2] && text.Pos(AName) == 1) - return node; - } - else { - if (text[1] != '<' && text.Pos(AName)) - return node; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ClearTreeNodeMap() { - tvClassMap.clear(); -} - -// --------------------------------------------------------------------------- -TTreeNode* __fastcall TFMain_11011981::FindTreeNodeByName(const String& name) { - TTreeNodeNameMap::const_iterator it = tvClassMap.find(name); - if (it != tvClassMap.end()) - return it->second; - - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AddTreeNodeWithName(TTreeNode* node, const String& name) { - tvClassMap[name] = node; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowClassViewer(DWORD VmtAdr) { - bool vmtProc; - WORD _dx, _bx, _si; - int cnt, vmtOfs, _pos; - DWORD parentAdr, adr = VmtAdr, vAdr, iAdr; - DWORD vmtAdresses[1024]; - String SelName = GetClsName(VmtAdr), line, name; - TTreeNode* selNode = 0; - TTreeNode* node = 0; - PInfoRec recN; - PMethodRec recM; - DISINFO disInfo; - - if (SelName == "" || !IsValidImageAdr(VmtAdr)) - return; - - if (!tsClassView->Enabled) - return; - - if (ClassTreeDone) { - node = GetNodeByName(SelName + " #" + Val2Str8(adr) + " Sz="); - if (node) { - node->Selected = true; - node->Expanded = true; - tvClassesFull->TopItem = node; - } - } - - TList *fieldsList = new TList; - TStringList *tmpList = new TStringList; - tmpList->Sorted = false; - - tvClassesShort->Items->Clear(); - node = 0; - - for (int n = 0; ; n++) { - parentAdr = GetParentAdr(adr); - vmtAdresses[n] = adr; - if (!parentAdr) { - while (n >= 0) { - adr = vmtAdresses[n]; - n--; - String className = GetClsName(adr); - int m, size = GetClassSize(adr); - if (DelphiVersion >= 2009) - size += 4; - - String text = className + " #" + Val2Str8(adr) + " Sz=" + Val2Str0(size); - - if (!node) // Root - node = tvClassesShort->Items->Add(0, text); - else - node = tvClassesShort->Items->AddChild(node, text); - - if (adr == VmtAdr && SameText(className, SelName)) - selNode = node; - - // Interfaces - int intfsNum = LoadIntfTable(adr, tmpList); - if (intfsNum) { - for (m = 0; m < intfsNum; m++) { - String item = tmpList->Strings[m]; - sscanf(AnsiString(item).c_str(), "%lX", &vAdr); - if (IsValidCodeAdr(vAdr)) { - int pos = item.Pos(' '); - TTreeNode* intfsNode = tvClassesShort->Items->AddChild(node, " " + item.SubString(pos + 1, item.Length())); - cnt = 0; - pos = Adr2Pos(vAdr); - for (int v = 0; ; v += 4) { - if (IsFlagSet(cfVTable, pos)) - cnt++; - if (cnt == 2) - break; - iAdr = *((DWORD*)(Code + pos)); - DWORD _adr = iAdr; - _pos = Adr2Pos(_adr); - vmtProc = false; - vmtOfs = 0; - _dx = 0; - _bx = 0; - _si = 0; - while (1) { - int instrlen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &disInfo, 0); - if ((disInfo.OpType[0] == otMEM || disInfo.OpType[1] == otMEM) && disInfo.BaseReg != 20) - // to exclude instruction "xchg reg, [esp]" - { - vmtOfs = disInfo.Offset; - } - if (disInfo.OpType[0] == otREG && disInfo.OpType[1] == otIMM) { - if (disInfo.OpRegIdx[0] == 10) // dx - _dx = disInfo.Immediate; - else if (disInfo.OpRegIdx[0] == 11) // bx - _bx = disInfo.Immediate; - else if (disInfo.OpRegIdx[0] == 14) // si - _si = disInfo.Immediate; - } - if (disInfo.Call) { - recN = GetInfoRec(disInfo.Immediate); - if (recN) { - if (recN->SameName("@CallDynaInst") || recN->SameName("@CallDynaClass")) { - if (DelphiVersion <= 5) - GetDynaInfo(adr, _bx, &iAdr); - else - GetDynaInfo(adr, _si, &iAdr); - break; - } - else if (recN->SameName("@FindDynaInst") || recN->SameName("@FindDynaClass")) { - GetDynaInfo(adr, _dx, &iAdr); - break; - } - } - } - if (disInfo.Branch && !disInfo.Conditional) { - if (IsValidImageAdr(disInfo.Immediate)) { - iAdr = disInfo.Immediate; - } - else { - vmtProc = true; - iAdr = *((DWORD*)(Code + Adr2Pos(VmtAdr - VmtSelfPtr + vmtOfs))); - recM = GetMethodInfo(VmtAdr, 'V', vmtOfs); - if (recM) - name = recM->name; - } - break; - } - else if (disInfo.Ret) { - vmtProc = true; - iAdr = *((DWORD*)(Code + Adr2Pos(VmtAdr - VmtSelfPtr + vmtOfs))); - recM = GetMethodInfo(VmtAdr, 'V', vmtOfs); - if (recM) - name = recM->name; - break; - } - _pos += instrlen; - _adr += instrlen; - } - if (!vmtProc && IsValidImageAdr(iAdr)) { - recN = GetInfoRec(iAdr); - if (recN && recN->HasName()) - name = recN->GetName(); - else - name = ""; - } - line = "I" + Val2Str4(v) + " #" + Val2Str8(iAdr); - if (name != "") - line += " " + name; - tvClassesShort->Items->AddChild(intfsNode, line); - pos += 4; - } - } - else { - TTreeNode* intfsNode = tvClassesShort->Items->AddChild(node, " " + item); - } - } - } - // Automated - int autoNum = LoadAutoTable(adr, tmpList); - if (autoNum) { - TTreeNode* autoNode = tvClassesShort->Items->AddChild(node, ""); - for (m = 0; m < autoNum; m++) { - tvClassesShort->Items->AddChild(autoNode, tmpList->Strings[m]); - } - } - // Fields - int fieldsNum = LoadFieldTable(adr, fieldsList); - if (fieldsNum) { - TTreeNode* fieldsNode = tvClassesShort->Items->AddChild(node, ""); - for (m = 0; m < fieldsNum; m++) { - PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[m]; - text = Val2Str5(fInfo->Offset) + " "; - if (fInfo->Name != "") - text += fInfo->Name; - else - text += "?"; - text += ":"; - if (fInfo->Type != "") - text += TrimTypeName(fInfo->Type); - else - text += "?"; - - tvClassesShort->Items->AddChild(fieldsNode, text); - } - } - // Events - int methodsNum = LoadMethodTable(adr, tmpList); - if (methodsNum) { - tmpList->Sort(); - TTreeNode* methodsNode = tvClassesShort->Items->AddChild(node, ""); - for (m = 0; m < methodsNum; m++) { - tvClassesShort->Items->AddChild(methodsNode, tmpList->Strings[m]); - } - } - int dynamicsNum = LoadDynamicTable(adr, tmpList); - if (dynamicsNum) { - tmpList->Sort(); - TTreeNode* dynamicsNode = FMain_11011981->tvClassesShort->Items->AddChild(node, ""); - for (m = 0; m < dynamicsNum; m++) { - tvClassesShort->Items->AddChild(dynamicsNode, tmpList->Strings[m]); - } - } - // Virtual - int virtualsNum = LoadVirtualTable(adr, tmpList); - if (virtualsNum) { - TTreeNode* virtualsNode = tvClassesShort->Items->AddChild(node, ""); - for (m = 0; m < virtualsNum; m++) { - tvClassesShort->Items->AddChild(virtualsNode, tmpList->Strings[m]); - } - } - } - if (selNode) { - selNode->Selected = true; - selNode->Expand(true); - tvClassesShort->TopItem = selNode; - } - break; - } - adr = parentAdr; - } - - delete fieldsList; - delete tmpList; - - pcWorkArea->ActivePage = tsClassView; - if (!rgViewerMode->ItemIndex) { - tvClassesFull->BringToFront(); - // if (tvClassesFull->CanFocus()) ActiveControl = tvClassesFull; - } - else { - tvClassesShort->BringToFront(); - // if (tvClassesShort->CanFocus()) ActiveControl = tvClassesShort; - } -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadIntfTable(DWORD adr, TStringList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->interfaces) { - for (int n = 0; n < recN->vmtInfo->interfaces->Count; n++) { - dstList->Add(recN->vmtInfo->interfaces->Strings[n]); - } - } - dstList->Sort(); - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadAutoTable(DWORD adr, TStringList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'A') { - String line = "A" + Val2Str4(recM->id) + " #" + Val2Str8(recM->address) + " " + recM->name; - dstList->Add(line); - } - } - } - dstList->Sort(); - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadFieldTable(DWORD adr, TList* dstList) { - dstList->Clear(); - DWORD parentSize = GetParentSize(adr); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->fields) { - for (int n = 0; n < recN->vmtInfo->fields->Count; n++) { - PFIELDINFO fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; - if (fInfo->Offset >= parentSize) { - bool exist = false; - for (int m = 0; m < dstList->Count; m++) { - PFIELDINFO fInfo1 = (PFIELDINFO)dstList->Items[m]; - if (fInfo1->Offset == fInfo->Offset) { - exist = true; - break; - } - } - if (!exist) - dstList->Add((void*)fInfo); - } - } - } - /* - while (1) - { - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->info && recN->info.vmtInfo->fields) - { - for (int n = recN->info.vmtInfo->fields->Count - 1; n >= 0; n--) - { - PFIELDINFO fInfo = (PFIELDINFO)recN->info.vmtInfo->fields->Items[n]; - if (!GetVMTField(dstList, fInfo->offset)) dstList->Add((void*)fInfo); - } - } - //ParentAdr - adr = GetParentAdr(adr); - if (!adr) break; - } - */ - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadMethodTable(DWORD adr, TList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - String className = GetClsName(adr) + "."; - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'M') { - if (recM->name.Pos(".") == 0 || recM->name.Pos(className) == 1) - dstList->Add((void*)recM); - } - } - } - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadMethodTable(DWORD adr, TStringList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'M') { - String line = "#" + Val2Str8(recM->address) + " " + recM->name; - dstList->Add(line); - } - } - } - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadDynamicTable(DWORD adr, TList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - String className = GetClsName(adr) + "."; - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'D') { - if (recM->name.Pos(".") == 0 || recM->name.Pos(className) == 1) - dstList->Add((void*)recM); - } - } - } - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadDynamicTable(DWORD adr, TStringList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'D') { - String line = "D" + Val2Str4(recM->id) + " #" + Val2Str8(recM->address) + " " + recM->name; - dstList->Add(line); - } - } - dstList->Sort(); - } - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadVirtualTable(DWORD adr, TList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - String className = GetClsName(adr) + "."; - recN->vmtInfo->methods->Sort(MethodsCmpFunction); - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'V') { - if (recM->name.Pos(".") == 0 || recM->name.Pos(className) == 1) - dstList->Add((void*)recM); - } - } - } - return dstList->Count; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadVirtualTable(DWORD adr, TStringList* dstList) { - dstList->Clear(); - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - recN->vmtInfo->methods->Sort(MethodsCmpFunction); - for (int n = 0; n < recN->vmtInfo->methods->Count; n++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[n]; - if (recM->kind == 'V') // && recM->id >= -4) - { - String line = ""; - PInfoRec recN1 = GetInfoRec(recM->address); - - if (recM->id < 0) - line += "-" + Val2Str4(-(recM->id)); - else - line += "V" + Val2Str4(recM->id); - - line += " #" + Val2Str8(recM->address); - if (recM->name != "") { - line += + " " + recM->name; - if (recN1 && recN1->HasName() && !recN1->SameName(recM->name)) { - // Change "@AbstractError" to "abstract" - if (SameText(recN1->GetName(), "@AbstractError")) - line += " (abstract)"; - else - line += " (" + recN1->GetName() + ")"; - } - } - else { - if (recN1 && recN1->HasName()) - line += " " + recN1->GetName(); - } - - dstList->Add(line); - } - } - } - return dstList->Count; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miViewProtoClick(TObject *Sender) { - int Idx; - DWORD Adr; - PInfoRec recN; - MProcInfo pInfo; - String item; - DISINFO DisInfo; - - if (lbCode->ItemIndex <= 0) - return; - - item = lbCode->Items->Strings[lbCode->ItemIndex]; - sscanf(AnsiString(item).c_str() + 1, "%lX", &Adr); - int instrlen = Disasm.Disassemble(Code + Adr2Pos(Adr), (__int64)Adr, &DisInfo, 0); - if (!instrlen) - return; - - String proto = ""; - if (DisInfo.Call) { - // Àäðåñ çàäàí ÿâíî - if (IsValidCodeAdr(DisInfo.Immediate)) { - recN = GetInfoRec(DisInfo.Immediate); - if (recN) - proto = recN->MakePrototype(DisInfo.Immediate, true, false, false, true, true); - } - // Àäðåñ íå çàäàí, ïðîáóåì ïè-êîä - else { - recN = GetInfoRec(Adr); - if (recN && recN->picode && IsValidCodeAdr(recN->picode->Ofs.Address)) { - if (KnowledgeBase.GetProcInfo(AnsiString(recN->picode->Name).c_str(), INFO_ARGS, &pInfo, &Idx)) - proto = KnowledgeBase.GetProcPrototype(&pInfo); - } - } - } - if (proto != "") { - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->Caption = "Prototype"; - FStringInfo_11011981->memStringInfo->Lines->Add(proto); - FStringInfo_11011981->ShowModal(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowCXrefsClick(TObject *Sender) { - if (lbCXrefs->Visible) { - ShowCXrefs->BevelOuter = bvRaised; - lbCXrefs->Visible = false; - } - else { - ShowCXrefs->BevelOuter = bvLowered; - lbCXrefs->Visible = true; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::bCodePrevClick(TObject *Sender) { - // first add to array current subroutine info (for ->) - if (CodeHistoryPtr == CodeHistorySize - 1) { - CodeHistorySize += HISTORY_CHUNK_LENGTH; - CodeHistory.Length = CodeHistorySize; - } - - PROCHISTORYREC rec; - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - memmove(&CodeHistory[CodeHistoryPtr + 1], &rec, sizeof(PROCHISTORYREC)); - // next pop from array - PPROCHISTORYREC prec = CodeHistoryPop(); - if (prec) - ShowCode(prec->adr, prec->itemIdx, prec->xrefIdx, prec->topIdx); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::bCodeNextClick(TObject *Sender) { - PROCHISTORYREC rec; - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - - CodeHistoryPtr++; - memmove(&CodeHistory[CodeHistoryPtr], &rec, sizeof(PROCHISTORYREC)); - - PPROCHISTORYREC prec = &CodeHistory[CodeHistoryPtr + 1]; - ShowCode(prec->adr, prec->itemIdx, prec->xrefIdx, prec->topIdx); - - bCodePrev->Enabled = (CodeHistoryPtr >= 0); - bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::CodeHistoryPush(PPROCHISTORYREC rec) { - if (CodeHistoryPtr == CodeHistorySize - 1) { - CodeHistorySize += HISTORY_CHUNK_LENGTH; - CodeHistory.Length = CodeHistorySize; - } - - CodeHistoryPtr++; - memmove(&CodeHistory[CodeHistoryPtr], rec, sizeof(PROCHISTORYREC)); - - CodeHistoryMax = CodeHistoryPtr; - bCodePrev->Enabled = (CodeHistoryPtr >= 0); - bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); -} - -// --------------------------------------------------------------------------- -PPROCHISTORYREC __fastcall TFMain_11011981::CodeHistoryPop() { - PPROCHISTORYREC prec = 0; - if (CodeHistoryPtr >= 0) { - prec = &CodeHistory[CodeHistoryPtr]; - CodeHistoryPtr--; - } - bCodePrev->Enabled = (CodeHistoryPtr >= 0); - bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); - return prec; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::tvClassesDblClick(TObject *Sender) { - int k, m, n; - TTreeView* tv; - PROCHISTORYREC rec; - - if (ActiveControl == tvClassesFull || ActiveControl == tvClassesShort) - tv = (TTreeView*)ActiveControl; - - TTreeNode *node = tv->Selected; - if (node) { - DWORD adr; - String line = node->Text; - int pos = line.Pos("#"); - // Óêàçàí àäðåñ - if (pos && !line.Pos("Sz=")) { - sscanf(AnsiString(line).c_str() + pos, "%lX", &adr); - if (IsValidCodeAdr(adr)) { - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(adr, 0, -1, -1); - CodeHistoryPush(&rec); - } - return; - } - // Óêàçàí òèï ïîëÿ - if (line.Pos(":")) { - String typeName = ExtractType(line); - // Åñëè òèï çàäàí â âèäå Unit.TypeName - if (typeName.Pos(".")) - typeName = ExtractProcName(typeName); - - adr = GetClassAdr(typeName); - if (IsValidImageAdr(adr)) { - ShowClassViewer(adr); - } - else { - WORD* uses = KnowledgeBase.GetTypeUses(AnsiString(typeName).c_str()); - int Idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(typeName).c_str()); - if (Idx != -1) { - Idx = KnowledgeBase.TypeOffsets[Idx].NamId; - MTypeInfo tInfo; - if (KnowledgeBase.GetTypeInfo(Idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS, &tInfo)) { - FTypeInfo_11011981->ShowKbInfo(&tInfo); - // as delete tInfo; - } - } - if (uses) - delete[]uses; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::tvClassesShortKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_RETURN) - tvClassesDblClick(Sender); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmVMTsPopup(TObject *Sender) { - bool b; - if (ActiveControl == tvClassesFull) { - b = (tvClassesFull->Items->Count != 0); - miSearchVMT->Visible = b; - miCollapseAll->Visible = b; - miEditClass->Visible = false; - return; - } - if (ActiveControl == tvClassesShort) { - b = (tvClassesShort->Items->Count != 0); - miSearchVMT->Visible = b; - miCollapseAll->Visible = b; - miEditClass->Visible = !AnalyzeThread && b && tvClassesShort->Selected; - return; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miViewClassClick(TObject *Sender) { - String sName = InputDialogExec("Enter Name of Type", "Name:", ""); - if (sName != "") - ShowClassViewer(GetClassAdr(sName)); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchVMTClick(TObject *Sender) { - WhereSearch = SEARCH_CLASSVIEWER; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < VMTsSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(VMTsSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (ActiveControl == tvClassesFull) { - if (tvClassesFull->Selected) - TreeSearchFrom = tvClassesFull->Selected; - else - TreeSearchFrom = tvClassesFull->Items->Item[0]; - } - else if (ActiveControl == tvClassesShort) { - if (tvClassesShort->Selected) - BranchSearchFrom = tvClassesShort->Selected; - else - BranchSearchFrom = tvClassesShort->Items->Item[0]; - } - - VMTsSearchText = FindDlg_11011981->cbText->Text; - if (VMTsSearchList->IndexOf(VMTsSearchText) == -1) - VMTsSearchList->Add(VMTsSearchText); - FindText(VMTsSearchText); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCollapseAllClick(TObject *Sender) { - TTreeView* tv; - if (ActiveControl == tvClassesFull || ActiveControl == tvClassesShort) { - tv = (TTreeView*)ActiveControl; - tv->Items->BeginUpdate(); - TTreeNode* rootNode = tv->Items->Item[0]; - const int cnt = rootNode->Count; - for (int n = 0; n < cnt; n++) { - TTreeNode* node = rootNode->Item[n]; - if (node->HasChildren && node->Expanded) - node->Collapse(true); - } - tv->Items->EndUpdate(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miEditClassClick(TObject *Sender) { - if (ActiveControl == tvClassesShort) { - TTreeNode* node = tvClassesShort->Selected; - if (node) { - int FieldOfs = -1; - if (!node->Text.Pos("#")) - sscanf(AnsiString(node->Text).c_str(), "%lX", &FieldOfs); - while (node) { - int pos = node->Text.Pos("#"); - // Óêàçàí àäðåñ - if (pos && node->Text.Pos("Sz=")) { - DWORD vmtAdr; - sscanf(AnsiString(node->Text).c_str() + pos, "%lX", &vmtAdr); - if (IsValidImageAdr(vmtAdr)) { - FEditFieldsDlg_11011981->VmtAdr = vmtAdr; - FEditFieldsDlg_11011981->FieldOffset = FieldOfs; - if (FEditFieldsDlg_11011981->Visible) - FEditFieldsDlg_11011981->Close(); - FEditFieldsDlg_11011981->FormStyle = fsStayOnTop; - FEditFieldsDlg_11011981->Show(); - return; - } - } - node = node->GetPrev(); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCopyCodeClick(TObject *Sender) { - Copy2Clipboard(lbCode->Items, 1, true); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbFormsDblClick(TObject *Sender) { - int n, m; - - TDfm *dfm = (TDfm*)ResInfo->FormList->Items[lbForms->ItemIndex]; - switch (rgViewFormAs->ItemIndex) { - // As Text - case 0: - FExplorer_11011981->tsCode->TabVisible = false; - FExplorer_11011981->tsData->TabVisible = false; - FExplorer_11011981->tsString->TabVisible = false; - FExplorer_11011981->tsText->TabVisible = true; - FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsText; - ResInfo->GetFormAsText(dfm, FExplorer_11011981->lbText->Items); - FExplorer_11011981->ShowModal(); - break; - // As Form - case 1: - if (dfm->Open != 2) { - // Åñëè åñòü îòêðûòûå ôîðìû, çàêðûâàåì èõ - ResInfo->CloseAllForms(); - - ShowDfm(dfm); - } - break; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowDfm(TDfm* dfm) { - if (!dfm) - return; - - // if inherited find parent form - if ((dfm->Flags & FF_INHERITED) && !dfm->ParentDfm) - dfm->ParentDfm = ResInfo->GetParentDfm(dfm); - - dfm->Loader = new IdrDfmLoader(0); - dfm->Form = dfm->Loader->LoadForm(dfm->MemStream, dfm); - delete dfm->Loader; - dfm->Loader = 0; - - if (dfm->Form) { - PUnitRec recU = GetUnit(GetClassAdr(dfm->ClassName)); - if (recU) { - int stringLen = sprintf(StringBuf, "[#%03d] %s", recU->iniOrder, dfm->Form->Caption.c_str()); - dfm->Form->Caption = String(StringBuf, stringLen); - } - dfm->Open = 2; - dfm->Form->Show(); - - // if (!AnalyzeThread) - // sb->Panels->Items[0]->Text = "Press F11 to open form controls tree"; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbFormsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (lbForms->ItemIndex >= 0 && Key == VK_RETURN) - lbFormsDblClick(Sender); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbCodeKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - switch (Key) { - case VK_RETURN: - lbCodeDblClick(Sender); - break; - case VK_ESCAPE: - bCodePrevClick(Sender); - break; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::CleanProject() { - int n; - PInfoRec recN; - - if (Image) { - delete[]Image; - Image = 0; - } - if (Flags) { - delete[]Flags; - Flags = 0; - } - if (Infos) { - for (n = 0; n < TotalSize; n++) { - recN = GetInfoRec(Pos2Adr(n)); - if (recN) - delete recN; - } - delete[]Infos; - Infos = 0; - } - if (BSSInfos) { - for (n = 0; n < BSSInfos->Count; n++) { - recN = (PInfoRec)BSSInfos->Objects[n]; - if (recN) - delete recN; - } - - delete BSSInfos; - BSSInfos = 0; - } - - for (n = 0; n < SegmentList->Count; n++) { - PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; - delete segInfo; - } - SegmentList->Clear(); - - for (n = 0; n < ExpFuncList->Count; n++) { - PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[n]; - delete recE; - } - ExpFuncList->Clear(); - - for (n = 0; n < ImpFuncList->Count; n++) { - PImportNameRec recI = (PImportNameRec)ImpFuncList->Items[n]; - delete recI; - } - ImpFuncList->Clear(); - - VmtList->Clear(); - - for (n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - delete recU; - } - Units->Clear(); - UnitsNum = 0; - - for (n = 0; n < OwnTypeList->Count; n++) { - PTypeRec recT = (PTypeRec)OwnTypeList->Items[n]; - delete recT; - } - OwnTypeList->Clear(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::CloseProject() { - CleanProject(); - - ResInfo->CloseAllForms(); - - for (int n = 0; n < ResInfo->FormList->Count; n++) { - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - delete dfm; - } - - ResInfo->FormList->Clear(); - ResInfo->Aliases->Clear(); - if (ResInfo->hFormPlugin) { - FreeLibrary(ResInfo->hFormPlugin); - ResInfo->hFormPlugin = 0; - } - ResInfo->Counter = 0; - - OwnTypeList->Clear(); - - UnitsSearchList->Clear(); - RTTIsSearchList->Clear(); - UnitItemsSearchList->Clear(); - VMTsSearchList->Clear(); - FormsSearchList->Clear(); - StringsSearchList->Clear(); - NamesSearchList->Clear(); - - CodeHistoryPtr = -1; - CodeHistoryMax = CodeHistoryPtr; - CodeHistory.Length = 0; - - KnowledgeBase.Close(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::tvClassesFullClick(TObject *Sender) { - TreeSearchFrom = tvClassesFull->Selected; - WhereSearch = SEARCH_CLASSVIEWER; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::tvClassesShortClick(TObject *Sender) { - BranchSearchFrom = tvClassesShort->Selected; - WhereSearch = SEARCH_CLASSVIEWER; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FindText(String Text) { - int n, pos, idx = -1; - String line, findText, msg; - TTreeNode* node; - TTreeView* tv; - - if (Text == "") - return; - - msg = "Search string \"" + Text + "\" not found"; - - switch (WhereSearch) { - case SEARCH_UNITS: - for (n = UnitsSearchFrom; n < lbUnits->Items->Count; n++) { - if (AnsiContainsText(lbUnits->Items->Strings[n], Text)) { - idx = n; - break; - } - } - if (idx == -1) { - for (n = 0; n < UnitsSearchFrom; n++) { - if (AnsiContainsText(lbUnits->Items->Strings[n], Text)) { - idx = n; - break; - } - } - } - if (idx != -1) { - UnitsSearchFrom = (idx < lbUnits->Items->Count - 1) ? idx + 1 : 0; - lbUnits->ItemIndex = idx; - lbUnits->SetFocus(); - } - else { - ShowMessage(msg); - } - break; - case SEARCH_UNITITEMS: - for (n = UnitItemsSearchFrom; n < lbUnitItems->Items->Count; n++) { - if (AnsiContainsText(lbUnitItems->Items->Strings[n], Text)) { - idx = n; - break; - } - } - if (idx == -1) { - for (n = 0; n < UnitItemsSearchFrom; n++) { - if (AnsiContainsText(lbUnitItems->Items->Strings[n], Text)) { - idx = n; - break; - } - } - } - if (idx != -1) { - UnitItemsSearchFrom = (idx < lbUnitItems->Items->Count) ? idx + 1 : 0; - lbUnitItems->ItemIndex = idx; - lbUnitItems->SetFocus(); - } - else { - ShowMessage(msg); - } - break; - case SEARCH_RTTIS: - for (n = RTTIsSearchFrom; n < lbRTTIs->Items->Count; n++) { - if (AnsiContainsText(lbRTTIs->Items->Strings[n], Text)) { - idx = n; - break; - } - } - if (idx == -1) { - for (n = 0; n < RTTIsSearchFrom; n++) { - if (AnsiContainsText(lbRTTIs->Items->Strings[n], Text)) { - idx = n; - break; - } - } - } - if (idx != -1) { - RTTIsSearchFrom = (idx < lbRTTIs->Items->Count - 1) ? idx + 1 : 0; - lbRTTIs->ItemIndex = idx; - lbRTTIs->SetFocus(); - } - else { - ShowMessage(msg); - } - break; - case SEARCH_FORMS: - for (n = FormsSearchFrom; n < lbForms->Items->Count; n++) { - if (AnsiContainsText(lbForms->Items->Strings[n], Text)) { - idx = n; - break; - } - } - if (idx == -1) { - for (n = 0; n < FormsSearchFrom; n++) { - if (AnsiContainsText(lbForms->Items->Strings[n], Text)) { - idx = n; - break; - } - } - } - if (idx != -1) { - FormsSearchFrom = (idx < lbForms->Items->Count - 1) ? idx + 1 : 0; - lbForms->ItemIndex = idx; - lbForms->SetFocus(); - } - else { - ShowMessage(msg); - } - break; - case SEARCH_CLASSVIEWER: - if (!rgViewerMode->ItemIndex) { - node = TreeSearchFrom; - while (node) { - line = node->Text; - // Skip <> - if (line[1] != '<' && AnsiContainsText(line, Text)) { - idx = 0; - break; - } - node = node->GetNext(); - } - if (idx == -1 && tvClassesFull->Items->Count) { - node = tvClassesFull->Items->Item[0]; - while (node != TreeSearchFrom) { - line = node->Text; - // Skip <> - if (line[1] != '<' && AnsiContainsText(line, Text)) { - idx = 0; - break; - } - node = node->GetNext(); - } - } - if (idx != -1) { - TreeSearchFrom = (node->GetNext()) ? node->GetNext() : tvClassesFull->Items->Item[0]; - node->Selected = true; - node->Expanded = true; - tvClassesFull->Show(); - } - else { - ShowMessage(msg); - } - } - else { - node = BranchSearchFrom; - while (node) { - line = node->Text; - // Skip <> - if (line[1] != '<' && AnsiContainsText(line, Text)) { - idx = 0; - break; - } - node = node->GetNext(); - } - if (idx == -1 && tvClassesShort->Items->Count) { - node = tvClassesShort->Items->Item[0]; - while (node != BranchSearchFrom) { - line = node->Text; - // Skip <> - if (line[1] != '<' && AnsiContainsText(line, Text)) { - idx = 0; - break; - } - node = node->GetNext(); - } - } - if (idx != -1) { - BranchSearchFrom = (node->GetNext()) ? node->GetNext() : tvClassesShort->Items->Item[0]; - node->Selected = true; - node->Expanded = true; - tvClassesShort->Show(); - } - else { - ShowMessage(msg); - } - } - break; - case SEARCH_STRINGS: - for (n = StringsSearchFrom; n < lbStrings->Items->Count; n++) { - line = lbStrings->Items->Strings[n]; - pos = line.Pos("'"); - line = line.SubString(pos + 1, line.Length() - pos); - if (AnsiContainsText(line, Text)) { - idx = n; - break; - } - } - if (idx == -1) { - for (n = 0; n < StringsSearchFrom; n++) { - line = lbStrings->Items->Strings[n]; - pos = line.Pos("'"); - line = line.SubString(pos + 1, line.Length() - pos); - if (AnsiContainsText(line, Text)) { - idx = n; - break; - } - } - } - if (idx != -1) { - StringsSearchFrom = (idx < lbStrings->Items->Count - 1) ? idx + 1 : 0; - lbStrings->ItemIndex = idx; - lbStrings->SetFocus(); - } - else { - ShowMessage(msg); - } - break; - case SEARCH_NAMES: - for (n = NamesSearchFrom; n < lbNames->Items->Count; n++) { - line = lbNames->Items->Strings[n]; - if (AnsiContainsText(line, Text)) { - idx = n; - break; - } - } - if (idx == -1) { - for (n = 0; n < NamesSearchFrom; n++) { - line = lbNames->Items->Strings[n]; - if (AnsiContainsText(line, Text)) { - idx = n; - break; - } - } - } - if (idx != -1) { - NamesSearchFrom = (idx < lbNames->Items->Count - 1) ? idx + 1 : 0; - lbNames->ItemIndex = idx; - lbNames->SetFocus(); - } - else { - ShowMessage(msg); - } - break; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbFormsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbForms->CanFocus()) - ActiveControl = lbForms; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbCodeMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbCode->CanFocus()) - ActiveControl = lbCode; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::tvClassesFullMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (tvClassesFull->CanFocus()) - ActiveControl = tvClassesFull; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::tvClassesShortMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (tvClassesShort->CanFocus()) - ActiveControl = tvClassesShort; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::rgViewerModeClick(TObject *Sender) { - if (!rgViewerMode->ItemIndex) - tvClassesFull->BringToFront(); - else - tvClassesShort->BringToFront(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miClassTreeBuilderClick(TObject *Sender) { - miLoadFile->Enabled = false; - miOpenProject->Enabled = false; - miMRF->Enabled = false; - miSaveProject->Enabled = false; - miSaveDelphiProject->Enabled = false; - miMapGenerator->Enabled = false; - miCommentsGenerator->Enabled = false; - miIDCGenerator->Enabled = false; - miLister->Enabled = false; - miClassTreeBuilder->Enabled = false; - miKBTypeInfo->Enabled = false; - miCtdPassword->Enabled = false; - miHex2Double->Enabled = false; - - FProgressBar->Show(); - - AnalyzeThread = new TAnalyzeThread(FMain_11011981, FProgressBar, false); - AnalyzeThread->Resume(); -} - -// --------------------------------------------------------------------------- -// INI FILE -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::IniFileRead() { - int n, m, pos, version; - String str, filename, ident; - TMenuItem *item; - TIniFile *iniFile; - TFont *_font; - Vcl::Forms::TMonitor *_monitor; - - iniFile = new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); - - _font = new TFont; - _font->Name = iniFile->ReadString("Settings", "FontName", "Fixedsys"); - _font->Charset = iniFile->ReadInteger("Settings", "FontCharset", 1); - _font->Size = iniFile->ReadInteger("Settings", "FontSize", 9); - _font->Color = iniFile->ReadInteger("Settings", "FontColor", 0); - if (iniFile->ReadBool("Settings", "FontBold", False)) - _font->Style = _font->Style << fsBold; - if (iniFile->ReadBool("Settings", "FontItalic", False)) - _font->Style = _font->Style << fsItalic; - SetupAllFonts(_font); - delete _font; - - WrkDir = iniFile->ReadString("MainForm", "WorkingDir", AppDir); - - for (n = 0; n < Screen->MonitorCount; n++) { - _monitor = Screen->Monitors[n]; - if (_monitor->Primary) { - Left = iniFile->ReadInteger("MainForm", "Left", _monitor->WorkareaRect.Left); - Top = iniFile->ReadInteger("MainForm", "Top", _monitor->WorkareaRect.Top); - Width = iniFile->ReadInteger("MainForm", "Width", _monitor->WorkareaRect.Width()); - Height = iniFile->ReadInteger("MainForm", "Height", _monitor->WorkareaRect.Height()); - break; - } - } - pcInfo->Width = iniFile->ReadInteger("MainForm", "LeftWidth", Width / 5); - pcInfo->ActivePage = tsUnits; - lbUnitItems->Height = iniFile->ReadInteger("MainForm", "BottomHeight", Height / 8); - // Most Recent Files - - for (n = 0, m = 0; n < 8; n++) { - ident = "File" + String(n + 1); - str = iniFile->ReadString("Recent Executable Files", ident, ""); - pos = str.LastDelimiter(","); - if (pos) { - filename = str.SubString(2, pos - 3); // Modified by ZGL - version = str.SubString(pos + 1, str.Length() - pos).ToInt(); - } - else { - filename = str; - version = -1; - } - if (FileExists(filename)) { - item = miMRF->Items[m]; - m++; - item->Caption = filename; - item->Tag = version; - item->Visible = (filename != ""); - item->Enabled = true; - } - else { - iniFile->DeleteKey("Recent Executable Files", ident); - } - } - for (n = 9, m = 9; n < 17; n++) { - ident = "File" + String(n - 8); - filename = iniFile->ReadString("Recent Project Files", ident, ""); - if (FileExists(filename)) { - item = miMRF->Items[m]; - m++; - item->Caption = filename; - item->Tag = 0; - item->Visible = (item->Caption != ""); - item->Enabled = true; - } - else { - iniFile->DeleteKey("Recent Project Files", ident); - } - } - delete iniFile; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::IniFileWrite() { - TIniFile *iniFile = new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); - iniFile->WriteString("Settings", "FontName", lbCode->Font->Name); - iniFile->WriteInteger("Settings", "FontCharset", lbCode->Font->Charset); - iniFile->WriteInteger("Settings", "FontSize", lbCode->Font->Size); - iniFile->WriteInteger("Settings", "FontColor", lbCode->Font->Color); - iniFile->WriteBool("Settings", "FontBold", lbCode->Font->Style.Contains(fsBold)); - iniFile->WriteBool("Settings", "FontItalic", lbCode->Font->Style.Contains(fsItalic)); - - iniFile->WriteString("MainForm", "WorkingDir", WrkDir); - iniFile->WriteInteger("MainForm", "Left", Left); - iniFile->WriteInteger("MainForm", "Top", Top); - iniFile->WriteInteger("MainForm", "Width", Width); - iniFile->WriteInteger("MainForm", "Height", Height); - iniFile->WriteInteger("MainForm", "LeftWidth", pcInfo->Width); - iniFile->WriteInteger("MainForm", "BottomHeight", lbUnitItems->Height); - - // Delete all - int n; - String ident; - for (n = 0; n < 8; n++) - iniFile->DeleteKey("Recent Executable Files", "File" + String(n + 1)); - for (n = 9; n < 17; n++) - iniFile->DeleteKey("Recent Executable Files", "File" + String(n - 8)); - - // Fill - for (n = 0; n < 8; n++) { - TMenuItem *item = miMRF->Items[n]; - if (item->Visible && item->Enabled) - iniFile->WriteString("Recent Executable Files", "File" + String(n + 1), "\"" + item->Caption + "\"," + String(item->Tag)); - } - for (n = 9; n < 17; n++) { - TMenuItem *item = miMRF->Items[n]; - if (item->Visible && item->Enabled) - iniFile->WriteString("Recent Project Files", "File" + String(n - 8), "\"" + item->Caption + "\""); - } - - delete iniFile; -} - -// --------------------------------------------------------------------------- -// LOAD EXE AND IDP -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::IsExe(String FileName) { - IMAGE_DOS_HEADER DosHeader; - IMAGE_NT_HEADERS NTHeaders; - - FILE* f = fopen(AnsiString(FileName).c_str(), "rb"); - if (!f) - return false; - - fseek(f, 0, SEEK_SET); - // IDD_ERR_NOT_EXECUTABLE - int readed = fread(&DosHeader, 1, sizeof(IMAGE_DOS_HEADER), f); - - if (readed != sizeof(IMAGE_DOS_HEADER) || DosHeader.e_magic != IMAGE_DOS_SIGNATURE) { - fclose(f); - return false; - } - - fseek(f, DosHeader.e_lfanew, SEEK_SET); - // IDD_ERR_NOT_PE_EXECUTABLE - readed = fread(&NTHeaders, 1, sizeof(IMAGE_NT_HEADERS), f); - fclose(f); - if (readed != sizeof(IMAGE_NT_HEADERS) || NTHeaders.Signature != IMAGE_NT_SIGNATURE) { - return false; - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::IsIdp(String FileName) { - char buf[13]; - - FILE* f = fopen(AnsiString(FileName).c_str(), "rb"); - if (!f) - return false; - - fseek(f, 0, SEEK_SET); - fread(buf, 1, 12, f); - buf[12] = 0; - fclose(f); - - if (!strcmp(buf, "IDR proj v.3")) - return true; - return false; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miAutodetectVersionClick(TObject *Sender) { - LoadDelphiFile(0); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi2Click(TObject *Sender) { - LoadDelphiFile(2); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi3Click(TObject *Sender) { - LoadDelphiFile(3); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi4Click(TObject *Sender) { - LoadDelphiFile(4); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi5Click(TObject *Sender) { - LoadDelphiFile(5); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi6Click(TObject *Sender) { - LoadDelphiFile(6); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi7Click(TObject *Sender) { - LoadDelphiFile(7); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi2005Click(TObject *Sender) { - LoadDelphiFile(2005); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi2006Click(TObject *Sender) { - LoadDelphiFile(2006); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi2007Click(TObject *Sender) { - LoadDelphiFile(2007); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi2009Click(TObject *Sender) { - LoadDelphiFile(2009); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphi2010Click(TObject *Sender) { - LoadDelphiFile(2010); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphiXE1Click(TObject *Sender) { - LoadDelphiFile(2011); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphiXE2Click(TObject *Sender) { - LoadDelphiFile(2012); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphiXE3Click(TObject *Sender) { - LoadDelphiFile(2013); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miDelphiXE4Click(TObject *Sender) { - LoadDelphiFile(2014); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::LoadFile(String FileName, int version) { - if (ProjectModified) { - int res = Application->MessageBox(L"Save active Project?", L"Confirmation", MB_YESNOCANCEL); - if (res == IDCANCEL) - return; - if (res == IDYES) { - if (IDPFile == "") - IDPFile = ChangeFileExt(SourceFile, ".idp"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "IDP|*.idp"; - SaveDlg->FileName = IDPFile; - - if (SaveDlg->Execute()) - SaveProject(SaveDlg->FileName); - } - } - - if (IsExe(FileName)) { - CloseProject(); - Init(); - LoadDelphiFile1(FileName, version, true, true); - } - else if (IsIdp(FileName)) { - CloseProject(); - Init(); - OpenProject(FileName); - } - else { - ShowMessage("File " + FileName + " is not executable or IDR project file"); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::LoadDelphiFile(int version) { - DoOpenDelphiFile(version, "", true, true); -} - -// --------------------------------------------------------------------------- -// version: 0 for autodetect, else - exact version -// -void __fastcall TFMain_11011981::DoOpenDelphiFile(int version, String FileName, bool loadExp, bool loadImp) { - if (ProjectModified) { - int res = Application->MessageBox(L"Save active Project?", L"Confirmation", MB_YESNOCANCEL); - if (res == IDCANCEL) - return; - if (res == IDYES) { - if (IDPFile == "") - IDPFile = ChangeFileExt(SourceFile, ".idp"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "IDP|*.idp"; - SaveDlg->FileName = IDPFile; - - if (SaveDlg->Execute()) - SaveProject(SaveDlg->FileName); - } - } - if (FileName == "") { - OpenDlg->InitialDir = WrkDir; - OpenDlg->FileName = ""; - OpenDlg->Filter = "EXE, DLL|*.exe;*.dll|All files|*.*"; - if (OpenDlg->Execute()) - FileName = OpenDlg->FileName; - } - if (FileName != "") { - if (!FileExists(FileName)) { - ShowMessage("File " + FileName + " not exists"); - return; - } - CloseProject(); - Init(); - WrkDir = ExtractFileDir(FileName); - LoadDelphiFile1(FileName, version, loadExp, loadImp); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::LoadDelphiFile1(String FileName, int version, bool loadExp, bool loadImp) { - int pos, ver; - String dprName, KBFileName, msg; - - SourceFile = FileName; - FILE *f = fopen(AnsiString(FileName).c_str(), "rb"); - - Screen->Cursor = crHourGlass; - int res = LoadImage(f, loadExp, loadImp); - fclose(f); - - if (res <= 0) { - if (!res) - ShowMessage("LoadImage error"); - Screen->Cursor = crDefault; - return; - } - - FindExports(); - FindImports(); - - ResInfo->EnumResources(SourceFile); - ResInfo->ShowResources(lbForms); - tsForms->Enabled = (lbForms->Items->Count > 0); - - if (version == DELHPI_VERSION_AUTO) // Autodetect - { - DelphiVersion = GetDelphiVersion(); - if (DelphiVersion == 1) { - Screen->Cursor = crDefault; - ShowMessage("File " + FileName + " is probably Delphi 4, 5, 6, 7, 2005, 2006 or 2007 file, try manual selection"); - FInputDlg_11011981->Caption = "Enter number of version (4, 5, 6, 7, 2005, 2006 or 2007)"; - FInputDlg_11011981->edtName->Text = ""; - if (FInputDlg_11011981->ShowModal() == mrCancel) { - CleanProject(); - return; - } - if (!TryStrToInt(FInputDlg_11011981->edtName->Text.Trim(), DelphiVersion)) { - CleanProject(); - return; - } - } - if (DelphiVersion == -1) { - Screen->Cursor = crDefault; - ShowMessage("File " + FileName + " is probably not Delphi file"); - CleanProject(); - return; - } - } - else - DelphiVersion = version; - Screen->Cursor = crDefault; - - UserKnowledgeBase = false; - if (Application->MessageBox(L"Use native Knowledge Base?", L"Knowledge Base kind selection", MB_YESNO) == IDNO) { - OpenDlg->InitialDir = WrkDir; - OpenDlg->FileName = ""; - OpenDlg->Filter = "BIN|*.bin|All files|*.*"; - if (OpenDlg->Execute()) { - KBFileName = OpenDlg->FileName; - UserKnowledgeBase = true; - } - } - else - KBFileName = BinsDir + "kb" + DelphiVersion + ".bin"; - - if (KBFileName == "") { - ShowMessage("Knowledge Base file not selected"); - CleanProject(); - return; - } - - Screen->Cursor = crHourGlass; - res = KnowledgeBase.Open(AnsiString(KBFileName).c_str()); - - if (!res) { - Screen->Cursor = crDefault; - ShowMessage("Cannot open Knowledge Base file " + String(KBFileName) + " (may be incorrect Version)"); - CleanProject(); - return; - } - - SetVmtConsts(DelphiVersion); - InitSysProcs(); - - dprName = ExtractFileName(FileName); - pos = dprName.Pos("."); - if (pos) - dprName.SetLength(pos - 1); - - if (DelphiVersion == 2) - UnitsNum = GetUnits2(dprName); - else - UnitsNum = GetUnits(dprName); - - if (UnitsNum > 0) { - ShowUnits(false); - } - else { - // May be BCB file? - UnitsNum = GetBCBUnits(dprName); - if (!UnitsNum) { - Screen->Cursor = crDefault; - ShowMessage("Cannot find table of initialization and finalization procedures"); - CleanProject(); - return; - } - } - - if (DelphiVersion <= 2010) - Caption = "Interactive Delphi Reconstructor by crypto: " + SourceFile + " (Delphi-" + String(DelphiVersion) + ")"; - else - Caption = "Interactive Delphi Reconstructor by crypto: " + SourceFile + " (Delphi-XE" + String(DelphiVersion - 2010) + ")"; - - // Show code to allow user make something useful - tsCodeView->Enabled = true; - // ShowCode(EP, 0, -1, -1); - - bEP->Enabled = true; - // Ãà âðåìÿ çàãðóçêè ôàéëà îòêëþ÷àåì ïóíêòû ìåíþ - miLoadFile->Enabled = false; - miOpenProject->Enabled = false; - miMRF->Enabled = false; - miSaveProject->Enabled = false; - miSaveDelphiProject->Enabled = false; - lbCXrefs->Enabled = false; - - FProgressBar->Show(); - - AnalyzeThread = new TAnalyzeThread(FMain_11011981, FProgressBar, true); - AnalyzeThread->Resume(); - - WrkDir = ExtractFileDir(FileName); - lbCode->ItemIndex = -1; - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -// Actions after analyzing -void __fastcall TFMain_11011981::AnalyzeThreadDone(TObject* Sender) { - if (!AnalyzeThread) - return; - - AnalyzeThreadRetVal = AnalyzeThread->GetRetVal(); - if (AnalyzeThread->all && AnalyzeThreadRetVal >= LAST_ANALYZE_STEP) { - ProjectLoaded = true; - ProjectModified = true; - AddExe2MRF(SourceFile); - } - - FProgressBar->Close(); - // Restore menu items - miLoadFile->Enabled = true; - miOpenProject->Enabled = true; - miMRF->Enabled = true; - miSaveProject->Enabled = true; - miSaveDelphiProject->Enabled = true; - lbCXrefs->Enabled = true; - - miEditFunctionC->Enabled = true; - miEditFunctionI->Enabled = true; - miFuzzyScanKB->Enabled = true; - miSearchItem->Enabled = true; - miName->Enabled = true; - miViewProto->Enabled = true; - bDecompile->Enabled = true; - - miMapGenerator->Enabled = true; - miCommentsGenerator->Enabled = true; - miIDCGenerator->Enabled = true; - miLister->Enabled = true; - miKBTypeInfo->Enabled = true; - miCtdPassword->Enabled = IsValidCodeAdr(CtdRegAdr); - miHex2Double->Enabled = true; - - delete AnalyzeThread; - AnalyzeThread = 0; -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::ImportsValid(DWORD ImpRVA, DWORD ImpSize) { - if (ImpRVA || ImpSize) { - DWORD EntryRVA = ImpRVA; - DWORD EndRVA = ImpRVA + ImpSize; - IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; - - while (1) { - memmove(&ImportDescriptor, (Image + Adr2Pos(EntryRVA + ImageBase)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); - - if (!ImportDescriptor.OriginalFirstThunk && !ImportDescriptor.TimeDateStamp && !ImportDescriptor.ForwarderChain && !ImportDescriptor.Name && !ImportDescriptor.FirstThunk) - break; - - if (!IsValidImageAdr(ImportDescriptor.Name + ImageBase)) - return false; - int NameLength = strlen((char*)(Image + Adr2Pos(ImportDescriptor.Name + ImageBase))); - if (NameLength < 0 || NameLength > 256) - return false; - if (!IsValidModuleName(NameLength, Adr2Pos(ImportDescriptor.Name + ImageBase))) - return false; - - EntryRVA += sizeof(IMAGE_IMPORT_DESCRIPTOR); - if (EntryRVA >= EndRVA) - break; - } - } - return true; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::LoadImage(FILE* f, bool loadExp, bool loadImp) { - int i, n, m, bytes, pos, SectionsNum, ExpNum, NameLength; - DWORD DataEnd, Items; - String moduleName, modName, sEP; - String impFuncName; - IMAGE_DOS_HEADER DosHeader; - IMAGE_NT_HEADERS NTHeaders; - PIMAGE_SECTION_HEADER SectionHeaders; - char segname[9]; - char msg[1024]; - - fseek(f, 0L, SEEK_SET); - // IDD_ERR_NOT_EXECUTABLE - if (fread(&DosHeader, 1, sizeof(IMAGE_DOS_HEADER), f) != sizeof(IMAGE_DOS_HEADER) || DosHeader.e_magic != IMAGE_DOS_SIGNATURE) { - ShowMessage("File is not executable"); - return 0; - } - - fseek(f, DosHeader.e_lfanew, SEEK_SET); - // IDD_ERR_NOT_PE_EXECUTABLE - if (fread(&NTHeaders, 1, sizeof(IMAGE_NT_HEADERS), f) != sizeof(IMAGE_NT_HEADERS) || NTHeaders.Signature != IMAGE_NT_SIGNATURE) { - ShowMessage("File is not PE-executable"); - return 0; - } - // IDD_ERR_INVALID_PE_EXECUTABLE - if (NTHeaders.FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER) || NTHeaders.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ShowMessage("File is invalid 32-bit PE-executable"); - return 0; - } - // IDD_ERR_INVALID_PE_EXECUTABLE - SectionsNum = NTHeaders.FileHeader.NumberOfSections; - if (!SectionsNum) { - ShowMessage("File is invalid PE-executable"); - return 0; - } - // SizeOfOptionalHeader may be > than sizeof(IMAGE_OPTIONAL_HEADER) - fseek(f, NTHeaders.FileHeader.SizeOfOptionalHeader -sizeof(IMAGE_OPTIONAL_HEADER), SEEK_CUR); - SectionHeaders = new IMAGE_SECTION_HEADER[SectionsNum]; - - if (fread(SectionHeaders, 1, sizeof(IMAGE_SECTION_HEADER) * SectionsNum, f) != sizeof(IMAGE_SECTION_HEADER) * SectionsNum) { - ShowMessage("Invalid section headers"); - delete[]SectionHeaders; - return 0; - } - - ImageBase = NTHeaders.OptionalHeader.ImageBase; - ImageSize = NTHeaders.OptionalHeader.SizeOfImage; - EP = NTHeaders.OptionalHeader.AddressOfEntryPoint; - - TotalSize = 0; - DWORD rsrcVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - DWORD relocVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - // Fill SegmentList - for (i = 0; i < SectionsNum; i++) { - PSegmentInfo segInfo = new SegmentInfo; - segInfo->Start = SectionHeaders[i].VirtualAddress + ImageBase; - segInfo->Flags = SectionHeaders[i].Characteristics; - - if (i + 1 < SectionsNum) - segInfo->Size = SectionHeaders[i + 1].VirtualAddress - SectionHeaders[i].VirtualAddress; - else - segInfo->Size = SectionHeaders[i].Misc.VirtualSize; - - if (!SectionHeaders[i].SizeOfRawData) // uninitialized data - { - // segInfo->Size = SectionHeaders[i].Misc.VirtualSize; - segInfo->Flags |= 0x80000; - } - else if (SectionHeaders[i].VirtualAddress == rsrcVA || SectionHeaders[i].VirtualAddress == relocVA) { - // segInfo->Size = SectionHeaders[i].SizeOfRawData; - segInfo->Flags |= 0x80000; - } - else { - // segInfo->Size = SectionHeaders[i].SizeOfRawData; - TotalSize += segInfo->Size; - } - memset(segname, 0, 9); - memmove(segname, SectionHeaders[i].Name, 8); - segInfo->Name = String(segname); - SegmentList->Add((void*)segInfo); - } - // DataEnd = TotalSize; - - // Load Image into memory - Image = new BYTE[TotalSize]; - memset((void*)Image, 0, TotalSize); - int num; - BYTE *p = Image; - for (i = 0; i < SectionsNum; i++) { - if (SectionHeaders[i].VirtualAddress == rsrcVA || SectionHeaders[i].VirtualAddress == relocVA) - continue; - BYTE *sp = p; - fseek(f, SectionHeaders[i].PointerToRawData, SEEK_SET); - DWORD Items = SectionHeaders[i].SizeOfRawData; - if (Items) { - for (n = 0; Items >= MAX_ITEMS; n++) { - fread(p, 1, MAX_ITEMS, f); - Items -= MAX_ITEMS; - p += MAX_ITEMS; - } - if (Items) { - fread(p, 1, Items, f); - p += Items; - } - num = p - Image; - if (i + 1 < SectionsNum) - p = sp + (SectionHeaders[i + 1].VirtualAddress - SectionHeaders[i].VirtualAddress); - } - } - - CodeStart = 0; - Code = Image + CodeStart; - CodeBase = ImageBase + SectionHeaders[0].VirtualAddress; - - DWORD evalInitTable = TPEHeader::EvaluateInitTable(Image, TotalSize, CodeBase); - if (!evalInitTable) { - ShowMessage("Cannot find initialization table"); - delete[]SectionHeaders; - delete[]Image; - Image = 0; - return 0; - } - - DWORD evalEP = 0; - // Find instruction mov eax,offset InitTable - for (n = 0; n < TotalSize - 5; n++) { - if (Image[n] == 0xB8 && *((DWORD*)(Image + n + 1)) == evalInitTable) { - evalEP = n; - break; - } - } - // Scan up until bytes 0x55 (push ebp) and 0x8B,0xEC (mov ebp,esp) - if (evalEP) { - while (evalEP != 0) { - if (Image[evalEP] == 0x55 && Image[evalEP + 1] == 0x8B && Image[evalEP + 2] == 0xEC) - break; - evalEP--; - } - } - // Check evalEP - if (evalEP + CodeBase != NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase) { - sprintf(msg, "Possible invalid EP (NTHeader:%lX, Evaluated:%lX). Input valid EP?", NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase, evalEP + CodeBase); - if (Application->MessageBox(String(msg).c_str(), L"Confirmation", MB_YESNO) == IDYES) { - sEP = InputDialogExec("New EP", "EP:", Val2Str0(NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase)); - if (sEP != "") { - sscanf(AnsiString(sEP).c_str(), "%lX", &EP); - if (!IsValidImageAdr(EP)) { - delete[]SectionHeaders; - delete[]Image; - Image = 0; - return 0; - } - } - else { - delete[]SectionHeaders; - delete[]Image; - Image = 0; - return 0; - } - } - else { - delete[]SectionHeaders; - delete[]Image; - Image = 0; - return 0; - } - } - else { - EP = NTHeaders.OptionalHeader.AddressOfEntryPoint + ImageBase; - } - // Find DataStart - // DWORD _codeEnd = DataEnd; - // DataStart = CodeStart; - // for (i = 0; i < SectionsNum; i++) - // { - // if (SectionHeaders[i].VirtualAddress + ImageBase > EP) - // { - // _codeEnd = SectionHeaders[i].VirtualAddress; - // DataStart = SectionHeaders[i].VirtualAddress; - // break; - // } - // } - delete[]SectionHeaders; - - CodeSize = TotalSize; // _codeEnd - SectionHeaders[0].VirtualAddress; - // DataSize = DataEnd - DataStart; - // DataBase = ImageBase + DataStart; - - Flags = new DWORD[TotalSize]; - memset(Flags, cfUndef, sizeof(DWORD) * TotalSize); - Infos = new PInfoRec[TotalSize]; - memset(Infos, 0, sizeof(PInfoRec) * TotalSize); - BSSInfos = new TStringList; - BSSInfos->Sorted = true; - - if (loadExp) { - // Load Exports - DWORD ExpRVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - // DWORD ExpSize = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - - if (ExpRVA) { - IMAGE_EXPORT_DIRECTORY ExportDescriptor; - memmove(&ExportDescriptor, (Image + Adr2Pos(ExpRVA + ImageBase)), sizeof(IMAGE_EXPORT_DIRECTORY)); - ExpNum = ExportDescriptor.NumberOfFunctions; - DWORD ExpFuncNamPos = ExportDescriptor.AddressOfNames; - DWORD ExpFuncAdrPos = ExportDescriptor.AddressOfFunctions; - DWORD ExpFuncOrdPos = ExportDescriptor.AddressOfNameOrdinals; - - for (i = 0; i < ExpNum; i++) { - PExportNameRec recE = new ExportNameRec; - - DWORD dp = *((DWORD*)(Image + Adr2Pos(ExpFuncNamPos + ImageBase))); - NameLength = strlen((char*)(Image + Adr2Pos(dp + ImageBase))); - recE->name = String((char*)(Image + Adr2Pos(dp + ImageBase)), NameLength); - - WORD dw = *((WORD*)(Image + Adr2Pos(ExpFuncOrdPos + ImageBase))); - recE->address = *((DWORD*)(Image + Adr2Pos(ExpFuncAdrPos + 4 * dw + ImageBase))) + ImageBase; - recE->ord = dw + ExportDescriptor.Base; - ExpFuncList->Add((void*)recE); - - ExpFuncNamPos += 4; - ExpFuncOrdPos += 2; - } - ExpFuncList->Sort(ExportsCmpFunction); - } - } - - DWORD ImpRVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - DWORD ImpSize = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; - - if (loadImp && (ImpRVA || ImpSize)) { - if (!ImportsValid(ImpRVA, ImpSize)) { - ShowMessage("Imports not valid, will skip!"); - } - else { - // Load Imports - DWORD EntryRVA; // Next import decriptor RVA - DWORD EndRVA; // End of imports - DWORD ThunkRVA; // RVA of next thunk (from FirstThunk) - DWORD LookupRVA; - // RVA of next thunk (from OriginalFirstTunk or FirstThunk) - DWORD ThunkValue; - // Value of next thunk (from OriginalFirstTunk or FirstThunk) - WORD Hint; // Ordinal or hint of imported symbol - - IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; - - // DWORD fnProc = 0; - - // First import descriptor - EntryRVA = ImpRVA; - EndRVA = ImpRVA + ImpSize; - - while (1) { - memmove(&ImportDescriptor, (Image + Adr2Pos(EntryRVA + ImageBase)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); - // All descriptor fields are NULL - end of list, break - if (!ImportDescriptor.OriginalFirstThunk && !ImportDescriptor.TimeDateStamp && !ImportDescriptor.ForwarderChain && !ImportDescriptor.Name && !ImportDescriptor.FirstThunk) - break; - - NameLength = strlen((char*)(Image + Adr2Pos(ImportDescriptor.Name + ImageBase))); - moduleName = String((char*)(Image + Adr2Pos(ImportDescriptor.Name + ImageBase)), NameLength); - - int pos = moduleName.Pos("."); - if (pos) - modName = moduleName.SubString(1, pos - 1); - else - modName = moduleName; - - if (-1 == ImpModuleList->IndexOf(moduleName)) - ImpModuleList->Add(moduleName); - - // HINSTANCE hLib = LoadLibraryEx(moduleName.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); - - // Define the source of import names (OriginalFirstThunk or FirstThunk) - if (ImportDescriptor.OriginalFirstThunk) - LookupRVA = ImportDescriptor.OriginalFirstThunk; - else - LookupRVA = ImportDescriptor.FirstThunk; - - // ThunkRVA get from FirstThunk always - ThunkRVA = ImportDescriptor.FirstThunk; - // Get Imported Functions - while (1) { - // Names or ordinals get from LookupTable (this table can be inside OriginalFirstThunk or FirstThunk) - ThunkValue = *((DWORD*)(Image + Adr2Pos(LookupRVA + ImageBase))); - if (!ThunkValue) - break; - - // fnProc = 0; - PImportNameRec recI = new ImportNameRec; - - if (ThunkValue & 0x80000000) { - // By ordinal - Hint = (WORD)(ThunkValue & 0xFFFF); - - // if (hLib) fnProc = (DWORD)GetProcAddress(hLib, (char*)Hint); - - // Addresse get from FirstThunk only - // recI->name = modName + "." + String(Hint); - recI->name = String(Hint); - } - else { - // by name - Hint = *((WORD*)(Image + Adr2Pos(ThunkValue + ImageBase))); - NameLength = lstrlen((char*)(Image + Adr2Pos(ThunkValue + 2 + ImageBase))); - impFuncName = String((char*)(Image + Adr2Pos(ThunkValue + 2 + ImageBase)), NameLength); - - // if (hLib) - // { - // fnProc = (DWORD)GetProcAddress(hLib, impFuncName.c_str()); - // memmove((void*)(Image + ThunkRVA), (void*)&fnProc, sizeof(DWORD)); - // } - - recI->name = impFuncName; - } - recI->module = modName; - recI->address = ImageBase + ThunkRVA; - ImpFuncList->Add((void*)recI); - // - SetFlag(cfImport, Adr2Pos(recI->address)); - PInfoRec recN = new InfoRec(Adr2Pos(recI->address), ikData); - recN->SetName(impFuncName); - // - ThunkRVA += 4; - LookupRVA += 4; - } - EntryRVA += sizeof(IMAGE_IMPORT_DESCRIPTOR); - if (EntryRVA >= EndRVA) - break; - - // if (hLib) - // { - // FreeLibrary(hLib); - // hLib = NULL; - // } - } - ImpFuncList->Sort(ImportsCmpFunction); - } - } - return 1; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miOpenProjectClick(TObject *Sender) { - DoOpenProjectFile(""); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::DoOpenProjectFile(String FileName) { - char *buf; - int n, m, num, len, size, pos; - PInfoRec recN; - PUnitRec recU; - PTypeRec recT; - PFIELDINFO fInfo; - - if (ProjectModified) { - int res = Application->MessageBox(L"Save active Project?", L"Confirmation", MB_YESNOCANCEL); - if (res == IDCANCEL) - return; - if (res == IDYES) { - if (IDPFile == "") - IDPFile = ChangeFileExt(SourceFile, ".idp"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "IDP|*.idp"; - SaveDlg->FileName = IDPFile; - - if (SaveDlg->Execute()) - SaveProject(SaveDlg->FileName); - } - } - if (FileName == "") { - OpenDlg->InitialDir = WrkDir; - OpenDlg->FileName = ""; - OpenDlg->Filter = "IDP|*.idp"; - if (OpenDlg->Execute()) - FileName = OpenDlg->FileName; - } - if (FileName != "") { - if (!FileExists(FileName)) { - ShowMessage("File " + FileName + " not exists"); - return; - } - CloseProject(); - Init(); - WrkDir = ExtractFileDir(FileName); - OpenProject(FileName); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ReadNode(TStream* stream, TTreeNode* node, char* buf) { - // Count - int itemsCount; - stream->Read(&itemsCount, sizeof(itemsCount)); - - // Text - int len; - stream->Read(&len, sizeof(len)); - stream->Read(buf, len); - node->Text = String(buf, len); - FProgressBar->pb->StepIt(); - - for (int n = 0; n < itemsCount; n++) { - TTreeNode* snode = node->Owner->AddChild(node, ""); - ReadNode(stream, snode, buf); - } - Application->ProcessMessages(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::OpenProject(String FileName) { - bool _useFuzzy = true; - int n, m, k, u, pos, len, num, cnum, evnum, size, infosCnt, bssCnt, _ver; - int topIdxU, itemIdxU, topIdxI, itemIdxI, topIdxC; - String KBFileName; - PInfoRec recN; - - IDPFile = FileName; - - Screen->Cursor = crHourGlass; - FILE* projectFile = fopen(AnsiString(FileName).c_str(), "rb"); - // Read Delphi version and maximum length of buffer - fseek(projectFile, 12, SEEK_SET); - fread(&_ver, sizeof(_ver), 1, projectFile); - - DelphiVersion = _ver&~(USER_KNOWLEDGEBASE | SOURCE_LIBRARY); - UserKnowledgeBase = false; - SourceIsLibrary = (_ver & SOURCE_LIBRARY); - if (_ver & USER_KNOWLEDGEBASE) { - ShowMessage("Choose original Knowledge Base"); - OpenDlg->InitialDir = WrkDir; - OpenDlg->FileName = ""; - OpenDlg->Filter = "BIN|*.bin|All files|*.*"; - if (OpenDlg->Execute()) { - KBFileName = OpenDlg->FileName; - UserKnowledgeBase = true; - } - else { - ShowMessage("Native Knowledge Base will be used!"); - _useFuzzy = false; - } - } - if (!UserKnowledgeBase) - KBFileName = BinsDir + "kb" + DelphiVersion + ".bin"; - - MaxBufLen = 0; - fseek(projectFile, -4L, SEEK_END); - fread(&MaxBufLen, sizeof(MaxBufLen), 1, projectFile); - fclose(projectFile); - - if (!KnowledgeBase.Open(AnsiString(KBFileName).c_str())) { - Screen->Cursor = crDefault; - ShowMessage("Cannot open KnowledgeBase (may be incorrect Version)"); - return; - } - - Caption = "Interactive Delphi Reconstructor by crypto: " + IDPFile + " (D" + DelphiVersion + ")"; - - SetVmtConsts(DelphiVersion); - - // Disable menu items - miLoadFile->Enabled = false; - miOpenProject->Enabled = false; - miMRF->Enabled = false; - miSaveProject->Enabled = false; - miSaveDelphiProject->Enabled = false; - lbCXrefs->Enabled = false; - - Update(); - - char* buf = new BYTE[MaxBufLen]; - TMemoryStream* inStream = new TMemoryStream(); - inStream->LoadFromFile(IDPFile); - - char magic[12]; - inStream->Read(magic, 12); - inStream->Read(&_ver, sizeof(_ver)); - DelphiVersion = _ver&~(USER_KNOWLEDGEBASE | SOURCE_LIBRARY); - - inStream->Read(&EP, sizeof(EP)); - inStream->Read(&ImageBase, sizeof(ImageBase)); - inStream->Read(&ImageSize, sizeof(ImageSize)); - inStream->Read(&TotalSize, sizeof(TotalSize)); - inStream->Read(&CodeBase, sizeof(CodeBase)); - inStream->Read(&CodeSize, sizeof(CodeSize)); - inStream->Read(&CodeStart, sizeof(CodeStart)); - - inStream->Read(&DataBase, sizeof(DataBase)); - inStream->Read(&DataSize, sizeof(DataSize)); - inStream->Read(&DataStart, sizeof(DataStart)); - - // SegmentList - inStream->Read(&num, sizeof(num)); - for (n = 0; n < num; n++) { - PSegmentInfo segInfo = new SegmentInfo; - inStream->Read(&segInfo->Start, sizeof(segInfo->Start)); - inStream->Read(&segInfo->Size, sizeof(segInfo->Size)); - inStream->Read(&segInfo->Flags, sizeof(segInfo->Flags)); - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - segInfo->Name = String(buf, len); - SegmentList->Add((void*)segInfo); - } - - Image = new BYTE[TotalSize]; - Code = Image + CodeStart; - Data = Image + DataStart; - DWORD Items = TotalSize; - BYTE* pImage = Image; - - while (Items >= MAX_ITEMS) { - inStream->Read(pImage, MAX_ITEMS); - pImage += MAX_ITEMS; - Items -= MAX_ITEMS; - } - if (Items) - inStream->Read(pImage, Items); - - Flags = new DWORD[TotalSize]; - Items = TotalSize; - DWORD* pFlags = Flags; - - while (Items >= MAX_ITEMS) { - inStream->Read(pFlags, sizeof(DWORD)*MAX_ITEMS); - pFlags += MAX_ITEMS; - Items -= MAX_ITEMS; - } - if (Items) - inStream->Read(pFlags, sizeof(DWORD)*Items); - - Infos = new PInfoRec[TotalSize]; - memset((void*)Infos, 0, sizeof(PInfoRec)*TotalSize); - - inStream->Read(&infosCnt, sizeof(infosCnt)); - BYTE kind; - for (n = 0; n < TotalSize; n++) { - inStream->Read(&pos, sizeof(pos)); - if (pos == -1) - break; - inStream->Read(&kind, sizeof(kind)); - recN = new InfoRec(pos, kind); - recN->Load(inStream, buf); - } - // BSSInfos - BSSInfos = new TStringList; - inStream->Read(&bssCnt, sizeof(bssCnt)); - for (n = 0; n < bssCnt; n++) { - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - String _adr = String(buf, len); - inStream->Read(&kind, sizeof(kind)); - recN = new InfoRec(-1, kind); - recN->Load(inStream, buf); - BSSInfos->AddObject(_adr, (TObject*)recN); - } - BSSInfos->Sorted = true; - - lbCXrefs->Enabled = true; - - // Units - inStream->Read(&num, sizeof(num)); - - UnitsNum = num; - for (n = 0; n < UnitsNum; n++) { - PUnitRec recU = new UnitRec; - inStream->Read(&recU->trivial, sizeof(recU->trivial)); - inStream->Read(&recU->trivialIni, sizeof(recU->trivialIni)); - inStream->Read(&recU->trivialFin, sizeof(recU->trivialFin)); - inStream->Read(&recU->kb, sizeof(recU->kb)); - inStream->Read(&recU->fromAdr, sizeof(recU->fromAdr)); - inStream->Read(&recU->toAdr, sizeof(recU->toAdr)); - inStream->Read(&recU->finadr, sizeof(recU->finadr)); - inStream->Read(&recU->finSize, sizeof(recU->finSize)); - inStream->Read(&recU->iniadr, sizeof(recU->iniadr)); - inStream->Read(&recU->iniSize, sizeof(recU->iniSize)); - recU->matchedPercent = 0.0; - inStream->Read(&recU->iniOrder, sizeof(recU->iniOrder)); - recU->names = new TStringList; - int namesNum = 0; - inStream->Read(&namesNum, sizeof(namesNum)); - for (u = 0; u < namesNum; u++) { - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - SetUnitName(recU, String(buf, len)); - } - Units->Add((void*)recU); - } - UnitSortField = 0; - CurUnitAdr = 0; - topIdxU = 0; - itemIdxU = -1; - topIdxI = 0; - itemIdxI = -1; - - if (UnitsNum) { - inStream->Read(&UnitSortField, sizeof(UnitSortField)); - inStream->Read(&CurUnitAdr, sizeof(CurUnitAdr)); - inStream->Read(&topIdxU, sizeof(topIdxU)); - inStream->Read(&itemIdxU, sizeof(itemIdxU)); - // UnitItems - if (CurUnitAdr) { - inStream->Read(&topIdxI, sizeof(topIdxI)); - inStream->Read(&itemIdxI, sizeof(itemIdxI)); - } - } - - tsUnits->Enabled = true; - switch (UnitSortField) { - case 0: - miSortUnitsByAdr->Checked = true; - miSortUnitsByOrd->Checked = false; - miSortUnitsByNam->Checked = false; - break; - case 1: - miSortUnitsByAdr->Checked = false; - miSortUnitsByOrd->Checked = true; - miSortUnitsByNam->Checked = false; - break; - case 2: - miSortUnitsByAdr->Checked = false; - miSortUnitsByOrd->Checked = false; - miSortUnitsByNam->Checked = true; - break; - } - ShowUnits(true); - lbUnits->TopIndex = topIdxU; - lbUnits->ItemIndex = itemIdxU; - - ShowUnitItems(GetUnit(CurUnitAdr), topIdxI, itemIdxI); - - miRenameUnit->Enabled = true; - miSearchUnit->Enabled = true; - miSortUnits->Enabled = true; - miCopyList->Enabled = true; - - miEditFunctionC->Enabled = true; - miEditFunctionI->Enabled = true; - miFuzzyScanKB->Enabled = true; - miSearchItem->Enabled = true; - - // Types - inStream->Read(&num, sizeof(num)); - for (n = 0; n < num; n++) { - PTypeRec recT = new TypeRec; - inStream->Read(&recT->kind, sizeof(recT->kind)); - inStream->Read(&recT->adr, sizeof(recT->adr)); - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - recT->name = String(buf, len); - OwnTypeList->Add((void*)recT); - } - RTTISortField = 0; - if (num) - inStream->Read(&RTTISortField, sizeof(RTTISortField)); - // UpdateRTTIs - tsRTTIs->Enabled = true; - miSearchRTTI->Enabled = true; - miSortRTTI->Enabled = true; - - switch (RTTISortField) { - case 0: - miSortRTTIsByAdr->Checked = true; - miSortRTTIsByKnd->Checked = false; - miSortRTTIsByNam->Checked = false; - break; - case 1: - miSortRTTIsByAdr->Checked = false; - miSortRTTIsByKnd->Checked = true; - miSortRTTIsByNam->Checked = false; - break; - case 2: - miSortRTTIsByAdr->Checked = false; - miSortRTTIsByKnd->Checked = false; - miSortRTTIsByNam->Checked = true; - break; - } - ShowRTTIs(); - - // Forms - inStream->Read(&num, sizeof(num)); - for (n = 0; n < num; n++) { - TDfm* dfm = new TDfm; - // Flags - inStream->Read(&dfm->Flags, sizeof(dfm->Flags)); - // ResName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - dfm->ResName = String(buf, len); - // Name - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - dfm->Name = String(buf, len); - // ClassName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - dfm->ClassName = String(buf, len); - // MemStream - inStream->Read(&size, sizeof(size)); - dfm->MemStream->Size = size; - while (size >= 4096) { - inStream->Read(buf, 4096); - dfm->MemStream->Write(buf, 4096); - size -= 4096; - } - if (size) { - inStream->Read(buf, size); - dfm->MemStream->Write(buf, size); - } - // Events - dfm->Events = new TList; - inStream->Read(&evnum, sizeof(evnum)); - for (m = 0; m < evnum; m++) { - PEventInfo eInfo = new EventInfo; - // EventName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - eInfo->EventName = String(buf, len); - // ProcName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - eInfo->ProcName = String(buf, len); - dfm->Events->Add((void*)eInfo); - } - // Components - inStream->Read(&cnum, sizeof(cnum)); - if (cnum) { - dfm->Components = new TList; - for (m = 0; m < cnum; m++) { - PComponentInfo cInfo = new ComponentInfo; - // Inherited - inStream->Read(&cInfo->Inherit, sizeof(cInfo->Inherit)); - // HasGlyph - inStream->Read(&cInfo->HasGlyph, sizeof(cInfo->HasGlyph)); - // Name - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - cInfo->Name = String(buf, len); - // ClassName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - cInfo->ClassName = String(buf, len); - // Events - cInfo->Events = new TList; - inStream->Read(&evnum, sizeof(evnum)); - for (k = 0; k < evnum; k++) { - PEventInfo eInfo = new EventInfo; - // EventName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - eInfo->EventName = String(buf, len); - // ProcName - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - eInfo->ProcName = String(buf, len); - cInfo->Events->Add((void*)eInfo); - } - dfm->Components->Add((void*)cInfo); - } - } - ResInfo->FormList->Add((void*)dfm); - } - // UpdateForms - ResInfo->ShowResources(lbForms); - // Aliases - inStream->Read(&num, sizeof(num)); - for (n = 0; n < num; n++) { - inStream->Read(&len, sizeof(len)); - inStream->Read(buf, len); - ResInfo->Aliases->Add(String(buf, len)); - } - InitAliases(false); - tsForms->Enabled = (lbForms->Items->Count > 0); - - // CodeHistory - inStream->Read(&CodeHistorySize, sizeof(CodeHistorySize)); - inStream->Read(&CodeHistoryPtr, sizeof(CodeHistoryPtr)); - inStream->Read(&CodeHistoryMax, sizeof(CodeHistoryMax)); - bCodePrev->Enabled = (CodeHistoryPtr >= 0); - bCodeNext->Enabled = (CodeHistoryPtr < CodeHistoryMax); - - CodeHistory.Length = CodeHistorySize; - for (n = 0; n < CodeHistorySize; n++) - inStream->Read(&CodeHistory[n], sizeof(PROCHISTORYREC)); - - inStream->Read(&CurProcAdr, sizeof(CurProcAdr)); - inStream->Read(&topIdxC, sizeof(topIdxC)); - - // Important variables - inStream->Read(&HInstanceVarAdr, sizeof(HInstanceVarAdr)); - inStream->Read(&LastTls, sizeof(LastTls)); - - inStream->Read(&Reserved, sizeof(Reserved)); - inStream->Read(&LastResStrNo, sizeof(LastResStrNo)); - - inStream->Read(&CtdRegAdr, sizeof(CtdRegAdr)); - - // UpdateVmtList - FillVmtList(); - // UpdateCode - tsCodeView->Enabled = true; - miGoTo->Enabled = true; - miExploreAdr->Enabled = true; - miSwitchFlag->Enabled = cbMultipleSelection->Checked; - bEP->Enabled = true; - DWORD adr = CurProcAdr; - CurProcAdr = 0; - ShowCode(adr, 0, -1, topIdxC); - // UpdateStrings - tsStrings->Enabled = true; - miSearchString->Enabled = true; - ShowStrings(0); - // UpdateNames - tsNames->Enabled = true; - ShowNames(0); - - Update(); - - // Class Viewer - // Total nodes num (for progress bar) - int nodesNum; - inStream->Read(&nodesNum, sizeof(nodesNum)); - if (nodesNum) { - tvClassesFull->Items->BeginUpdate(); - TTreeNode* root = tvClassesFull->Items->Add(0, ""); - ReadNode(inStream, root, buf); - tvClassesFull->Items->EndUpdate(); - ClassTreeDone = true; - } - // UpdateClassViewer - tsClassView->Enabled = true; - miViewClass->Enabled = true; - miSearchVMT->Enabled = true; - miCollapseAll->Enabled = true; - miEditClass->Enabled = true; - - if (ClassTreeDone) { - TTreeNode *root = tvClassesFull->Items->Item[0]; - root->Expanded = true; - rgViewerMode->ItemIndex = 0; - rgViewerMode->Enabled = true; - tvClassesFull->BringToFront(); - } - else { - rgViewerMode->ItemIndex = 1; - rgViewerMode->Enabled = false; - tvClassesShort->BringToFront(); - } - miClassTreeBuilder->Enabled = true; - - // Just cheking - inStream->Read(&MaxBufLen, sizeof(MaxBufLen)); - - if (buf) - delete[]buf; - delete inStream; - - ProjectLoaded = true; - ProjectModified = false; - - AddIdp2MRF(FileName); - - // Enable lemu items - miLoadFile->Enabled = true; - miOpenProject->Enabled = true; - miMRF->Enabled = true; - miSaveProject->Enabled = true; - miSaveDelphiProject->Enabled = true; - - miEditFunctionC->Enabled = true; - miEditFunctionI->Enabled = true; - miFuzzyScanKB->Enabled = _useFuzzy; - miSearchItem->Enabled = true; - miName->Enabled = true; - miViewProto->Enabled = true; - bDecompile->Enabled = true; - - miMapGenerator->Enabled = true; - miCommentsGenerator->Enabled = true; - miIDCGenerator->Enabled = true; - miLister->Enabled = true; - miKBTypeInfo->Enabled = true; - miCtdPassword->Enabled = IsValidCodeAdr(CtdRegAdr); - miHex2Double->Enabled = true; - - WrkDir = ExtractFileDir(FileName); - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe1Click(TObject *Sender) { - LoadFile(miExe1->Caption, miMRF->Items[0]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe2Click(TObject *Sender) { - LoadFile(miExe2->Caption, miMRF->Items[1]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe3Click(TObject *Sender) { - LoadFile(miExe3->Caption, miMRF->Items[2]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe4Click(TObject *Sender) { - LoadFile(miExe4->Caption, miMRF->Items[3]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe5Click(TObject *Sender) { - LoadFile(miExe5->Caption, miMRF->Items[4]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe6Click(TObject *Sender) { - LoadFile(miExe6->Caption, miMRF->Items[5]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe7Click(TObject *Sender) { - LoadFile(miExe7->Caption, miMRF->Items[6]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miExe8Click(TObject *Sender) { - LoadFile(miExe8->Caption, miMRF->Items[7]->Tag); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp1Click(TObject *Sender) { - LoadFile(miIdp1->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp2Click(TObject *Sender) { - LoadFile(miIdp2->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp3Click(TObject *Sender) { - LoadFile(miIdp3->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp4Click(TObject *Sender) { - LoadFile(miIdp4->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp5Click(TObject *Sender) { - LoadFile(miIdp5->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp6Click(TObject *Sender) { - LoadFile(miIdp6->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp7Click(TObject *Sender) { - LoadFile(miIdp7->Caption, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIdp8Click(TObject *Sender) { - LoadFile(miIdp8->Caption, -1); -} - -// --------------------------------------------------------------------------- -// SAVE PROJECT -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSaveProjectClick(TObject *Sender) { - if (IDPFile == "") - IDPFile = ChangeFileExt(SourceFile, ".idp"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "IDP|*.idp"; - SaveDlg->FileName = IDPFile; - - if (SaveDlg->Execute()) - SaveProject(SaveDlg->FileName); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::WriteNode(TStream* stream, TTreeNode* node) { - // Count - int itemsCount = node->Count; - stream->Write(&itemsCount, sizeof(itemsCount)); - FProgressBar->pb->StepIt(); - - // Text - int len = node->Text.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - stream->Write(&len, sizeof(len)); - stream->Write(node->Text.c_str(), len); - - for (int n = 0; n < itemsCount; n++) { - WriteNode(stream, node->Item[n]); - } - Application->ProcessMessages(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::SaveProject(String FileName) { - int n, m, k, len, num, cnum, evnum, size, pos, res, infosCnt, topIdx, itemIdx; - TMemoryStream* outStream = 0; - BYTE buf[4096]; - - if (FileExists(FileName)) { - if (Application->MessageBox(L"File already exists. Overwrite?", L"Warning", MB_YESNO) == IDNO) - return; - } - - Screen->Cursor = crHourGlass; - IDPFile = FileName; - - try { - outStream = new TMemoryStream(); - - FProgressBar->Show(); - - char* magic = "IDR proj v.3"; - outStream->Write(magic, 12); - int _ver = DelphiVersion; - if (UserKnowledgeBase) - _ver |= USER_KNOWLEDGEBASE; - if (SourceIsLibrary) - _ver |= SOURCE_LIBRARY; - outStream->Write(&_ver, sizeof(_ver)); - - outStream->Write(&EP, sizeof(EP)); - outStream->Write(&ImageBase, sizeof(ImageBase)); - outStream->Write(&ImageSize, sizeof(ImageSize)); - outStream->Write(&TotalSize, sizeof(TotalSize)); - outStream->Write(&CodeBase, sizeof(CodeBase)); - outStream->Write(&CodeSize, sizeof(CodeSize)); - outStream->Write(&CodeStart, sizeof(CodeStart)); - - outStream->Write(&DataBase, sizeof(DataBase)); - outStream->Write(&DataSize, sizeof(DataSize)); - outStream->Write(&DataStart, sizeof(DataStart)); - // SegmentList - num = SegmentList->Count; - outStream->Write(&num, sizeof(num)); - for (n = 0; n < num; n++) { - PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; - outStream->Write(&segInfo->Start, sizeof(segInfo->Start)); - outStream->Write(&segInfo->Size, sizeof(segInfo->Size)); - outStream->Write(&segInfo->Flags, sizeof(segInfo->Flags)); - len = segInfo->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(segInfo->Name.c_str(), len); - } - - DWORD Items = TotalSize; - BYTE *pImage = Image; - FProgressBar->StartProgress("Writing Image...", "", (Items + MAX_ITEMS - 1) / MAX_ITEMS); - while (Items >= MAX_ITEMS) { - FProgressBar->pb->StepIt(); - outStream->Write(pImage, MAX_ITEMS); - pImage += MAX_ITEMS; - Items -= MAX_ITEMS; - } - if (Items) - outStream->Write(pImage, Items); - - Items = TotalSize; - DWORD *pFlags = Flags; - FProgressBar->StartProgress("Writing Flags...", "", (Items + MAX_ITEMS - 1) / MAX_ITEMS); - while (Items >= MAX_ITEMS) { - FProgressBar->pb->StepIt(); - outStream->Write(pFlags, sizeof(DWORD)*MAX_ITEMS); - pFlags += MAX_ITEMS; - Items -= MAX_ITEMS; - } - if (Items) - outStream->Write(pFlags, sizeof(DWORD)*Items); - - infosCnt = 0; - for (n = 0; n < TotalSize; n++) { - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN) - infosCnt++; - } - outStream->Write(&infosCnt, sizeof(infosCnt)); - - FProgressBar->StartProgress("Writing Infos Objects (number = " + String(infosCnt) + ")...", "", TotalSize / 4096); - MaxBufLen = 0; - BYTE kind; - try { - for (n = 0; n < TotalSize; n++) { - if ((n & 4095) == 0) { - FProgressBar->pb->StepIt(); - Application->ProcessMessages(); - } - - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN) { - // Position - pos = n; - outStream->Write(&pos, sizeof(pos)); - kind = recN->kind; - outStream->Write(&kind, sizeof(kind)); - recN->Save(outStream); - } - } - } - catch (Exception &exception) { - ShowMessage("Error at " + Val2Str8(Pos2Adr(n))); - } - // Last position = -1 -> end of items - pos = -1; - outStream->Write(&pos, sizeof(pos)); - - // BSSInfos - String _adr; - int bssCnt = BSSInfos->Count; - outStream->Write(&bssCnt, sizeof(bssCnt)); - for (n = 0; n < bssCnt; n++) { - _adr = BSSInfos->Strings[n]; - len = _adr.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(_adr.c_str(), len); - PInfoRec recN = (PInfoRec)BSSInfos->Objects[n]; - kind = recN->kind; - outStream->Write(&kind, sizeof(kind)); - recN->Save(outStream); - } - - // Units - num = UnitsNum; - FProgressBar->StartProgress("Writing Units (number = " + String(num) + ")...", "", num); - outStream->Write(&num, sizeof(num)); - for (n = 0; n < num; n++) { - FProgressBar->pb->StepIt(); - Application->ProcessMessages(); - PUnitRec recU = (PUnitRec)Units->Items[n]; - outStream->Write(&recU->trivial, sizeof(recU->trivial)); - outStream->Write(&recU->trivialIni, sizeof(recU->trivialIni)); - outStream->Write(&recU->trivialFin, sizeof(recU->trivialFin)); - outStream->Write(&recU->kb, sizeof(recU->kb)); - outStream->Write(&recU->fromAdr, sizeof(recU->fromAdr)); - outStream->Write(&recU->toAdr, sizeof(recU->toAdr)); - outStream->Write(&recU->finadr, sizeof(recU->finadr)); - outStream->Write(&recU->finSize, sizeof(recU->finSize)); - outStream->Write(&recU->iniadr, sizeof(recU->iniadr)); - outStream->Write(&recU->iniSize, sizeof(recU->iniSize)); - outStream->Write(&recU->iniOrder, sizeof(recU->iniOrder)); - int namesNum = recU->names->Count; - outStream->Write(&namesNum, sizeof(namesNum)); - for (int u = 0; u < namesNum; u++) { - len = recU->names->Strings[u].Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(recU->names->Strings[u].c_str(), len); - } - } - if (num) { - outStream->Write(&UnitSortField, sizeof(UnitSortField)); - outStream->Write(&CurUnitAdr, sizeof(CurUnitAdr)); - topIdx = lbUnits->TopIndex; - outStream->Write(&topIdx, sizeof(topIdx)); - itemIdx = lbUnits->ItemIndex; - outStream->Write(&itemIdx, sizeof(itemIdx)); - // UnitItems - if (CurUnitAdr) { - topIdx = lbUnitItems->TopIndex; - outStream->Write(&topIdx, sizeof(topIdx)); - itemIdx = lbUnitItems->ItemIndex; - outStream->Write(&itemIdx, sizeof(itemIdx)); - } - } - - // Types - num = OwnTypeList->Count; - FProgressBar->StartProgress("Writing Types (number = " + String(num) + ")...", "", num); - outStream->Write(&num, sizeof(num)); - for (n = 0; n < num; n++) { - FProgressBar->pb->StepIt(); - Application->ProcessMessages(); - PTypeRec recT = (PTypeRec)OwnTypeList->Items[n]; - outStream->Write(&recT->kind, sizeof(recT->kind)); - outStream->Write(&recT->adr, sizeof(recT->adr)); - len = recT->name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(recT->name.c_str(), len); - } - if (num) - outStream->Write(&RTTISortField, sizeof(RTTISortField)); - - // Forms - num = ResInfo->FormList->Count; - FProgressBar->StartProgress("Writing Forms (number = " + String(num) + ")...", "", num); - outStream->Write(&num, sizeof(num)); - for (n = 0; n < num; n++) { - FProgressBar->pb->StepIt(); - Application->ProcessMessages(); - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - // Flags - outStream->Write(&dfm->Flags, sizeof(dfm->Flags)); - // ResName - len = dfm->ResName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(dfm->ResName.c_str(), len); - // Name - len = dfm->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(dfm->Name.c_str(), len); - // ClassName - len = dfm->ClassName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(dfm->ClassName.c_str(), len); - // MemStream - size = dfm->MemStream->Size; - if (4096 > MaxBufLen) - MaxBufLen = 4096; - outStream->Write(&size, sizeof(size)); - dfm->MemStream->Seek(0, soFromBeginning); - while (size >= 4096) { - dfm->MemStream->Read(buf, 4096); - outStream->Write(buf, 4096); - size -= 4096; - } - if (size) { - dfm->MemStream->Read(buf, size); - outStream->Write(buf, size); - } - // Events - evnum = (dfm->Events) ? dfm->Events->Count : 0; - outStream->Write(&evnum, sizeof(evnum)); - for (m = 0; m < evnum; m++) { - PEventInfo eInfo = (PEventInfo)dfm->Events->Items[m]; - // EventName - len = eInfo->EventName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(eInfo->EventName.c_str(), len); - // ProcName - len = eInfo->ProcName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(eInfo->ProcName.c_str(), len); - } - // Components - cnum = (dfm->Components) ? dfm->Components->Count : 0; - outStream->Write(&cnum, sizeof(cnum)); - for (m = 0; m < cnum; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - // Inherited - outStream->Write(&cInfo->Inherit, sizeof(cInfo->Inherit)); - // HasGlyph - outStream->Write(&cInfo->HasGlyph, sizeof(cInfo->HasGlyph)); - // Name - len = cInfo->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(cInfo->Name.c_str(), len); - // ClassName - len = cInfo->ClassName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(cInfo->ClassName.c_str(), len); - // Events - evnum = (cInfo->Events) ? cInfo->Events->Count : 0; - outStream->Write(&evnum, sizeof(evnum)); - for (k = 0; k < evnum; k++) { - PEventInfo eInfo = (PEventInfo)cInfo->Events->Items[k]; - // EventName - len = eInfo->EventName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(eInfo->EventName.c_str(), len); - // ProcName - len = eInfo->ProcName.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(eInfo->ProcName.c_str(), len); - } - } - } - // Aliases - num = ResInfo->Aliases->Count; - FProgressBar->StartProgress("Writing Aliases (number = " + String(num) + ")...", "", num); - outStream->Write(&num, sizeof(num)); - for (n = 0; n < num; n++) { - FProgressBar->pb->StepIt(); - Application->ProcessMessages(); - len = ResInfo->Aliases->Strings[n].Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outStream->Write(&len, sizeof(len)); - outStream->Write(ResInfo->Aliases->Strings[n].c_str(), len); - } - - // CodeHistory - outStream->Write(&CodeHistorySize, sizeof(CodeHistorySize)); - outStream->Write(&CodeHistoryPtr, sizeof(CodeHistoryPtr)); - outStream->Write(&CodeHistoryMax, sizeof(CodeHistoryMax)); - PROCHISTORYREC phRec; - FProgressBar->StartProgress("Writing Code History Items (number = " + String(CodeHistorySize) + ")...", "", CodeHistorySize); - for (n = 0; n < CodeHistorySize; n++) { - FProgressBar->pb->StepIt(); - Application->ProcessMessages(); - outStream->Write(&CodeHistory[n], sizeof(PROCHISTORYREC)); - } - - outStream->Write(&CurProcAdr, sizeof(CurProcAdr)); - topIdx = lbCode->TopIndex; - outStream->Write(&topIdx, sizeof(topIdx)); - - // Important variables - outStream->Write(&HInstanceVarAdr, sizeof(HInstanceVarAdr)); - outStream->Write(&LastTls, sizeof(LastTls)); - - outStream->Write(&Reserved, sizeof(Reserved)); - outStream->Write(&LastResStrNo, sizeof(LastResStrNo)); - - outStream->Write(&CtdRegAdr, sizeof(CtdRegAdr)); - - FProgressBar->Close(); - // Class Viewer - // Total nodes (for progress) - num = 0; - if (ClassTreeDone) - num = tvClassesFull->Items->Count; - if (num && Application->MessageBox(L"Save full Tree of Classes?", L"Warning", MB_YESNO) == IDYES) { - FProgressBar->Show(); - outStream->Write(&num, sizeof(num)); - if (num) { - FProgressBar->StartProgress("Writing ClassViewer Tree Nodes (number = " + String(num) + ")...", "", num); - TTreeNode* root = tvClassesFull->Items->GetFirstNode(); - WriteNode(outStream, root); - } - FProgressBar->Close(); - } - else { - num = 0; - outStream->Write(&num, sizeof(num)); - } - // At end write MaxBufLen - outStream->Write(&MaxBufLen, sizeof(MaxBufLen)); - outStream->SaveToFile(IDPFile); - delete outStream; - - ProjectModified = false; - - AddIdp2MRF(FileName); - } - catch (EFCreateError &E) { - ShowMessage("Cannot open output file " + IDPFile); - } - - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AddExe2MRF(String FileName) { - int n, m; - for (n = 0; n < 8; n++) { - TMenuItem* item = miMRF->Items[n]; - if (SameText(FileName, item->Caption)) - break; - } - if (n == 8) - n--; - - for (m = n; m >= 1; m--) { - miMRF->Items[m]->Caption = miMRF->Items[m - 1]->Caption; - miMRF->Items[m]->Tag = miMRF->Items[m - 1]->Tag; - miMRF->Items[m]->Visible = (miMRF->Items[m]->Caption != ""); - } - miMRF->Items[0]->Caption = FileName; - miMRF->Items[0]->Tag = DelphiVersion; - miMRF->Items[0]->Visible = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AddIdp2MRF(String FileName) { - int n, m; - for (n = 9; n < 17; n++) { - TMenuItem* item = miMRF->Items[n]; - if (SameText(FileName, item->Caption)) - break; - } - if (n == 17) - n--; - - for (m = n; m >= 10; m--) { - miMRF->Items[m]->Caption = miMRF->Items[m - 1]->Caption; - miMRF->Items[m]->Visible = (miMRF->Items[m]->Caption != ""); - } - miMRF->Items[9]->Caption = FileName; - miMRF->Items[9]->Visible = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miKBTypeInfoClick(TObject *Sender) { - int idx; - MProcInfo pInfo; - MTypeInfo tInfo; - String typeName, className, propName, sName; - - sName = InputDialogExec("Enter Type Name", "Name:", ""); - if (sName != "") { - // Procedure - if (KnowledgeBase.GetKBProcInfo(sName, &pInfo, &idx)) { - FTypeInfo_11011981->memDescription->Clear(); - FTypeInfo_11011981->memDescription->Lines->Add(KnowledgeBase.GetProcPrototype(&pInfo)); - FTypeInfo_11011981->ShowModal(); - return; - } - // Type - if (KnowledgeBase.GetKBTypeInfo(sName, &tInfo)) { - FTypeInfo_11011981->ShowKbInfo(&tInfo); - return; - } - // Property - className = ExtractClassName(sName); - propName = ExtractProcName(sName); - while (1) { - if (KnowledgeBase.GetKBPropertyInfo(className, propName, &tInfo)) { - FTypeInfo_11011981->ShowKbInfo(&tInfo); - return; - } - className = GetParentName(className); - if (className == "") - break; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormResize(TObject *Sender) { - lbCode->Repaint(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::EditFunction(DWORD Adr) { - BYTE tag, callKind; - DWORD adr, rootAdr; - int n, m, a, cnt, size, ofs, offset, dotpos; - char *p; - PUnitRec recU; - PInfoRec recN, recN1; - PXrefRec recX; - PVmtListRec recV; - PMethodRec recM; - PARGINFO argInfo; - String line, name, typeDef, item, className, procName; - char buf[1024]; - - // if (Adr == EP) return; - - recU = GetUnit(Adr); - if (!recU) - return; - if (Adr == recU->iniadr || Adr == recU->finadr) - return; - - recN = GetInfoRec(Adr); - if (recN) { - FEditFunctionDlg_11011981->Adr = Adr; - - if (FEditFunctionDlg_11011981->ShowModal() == mrOk) { - // local vars - if (0) // recN->info.procInfo->locals) - { - cnt = FEditFunctionDlg_11011981->lbVars->Count; - recN->procInfo->DeleteLocals(); - for (n = 0; n < cnt; n++) { - line = FEditFunctionDlg_11011981->lbVars->Items->Strings[n]; - // '-' - deleted line - strcpy(buf, AnsiString(line).c_str()); - p = strtok(buf, " "); - // offset - sscanf(p, "%lX", &offset); - // size - p = strtok(0, " "); - sscanf(p, "%lX", &size); - // name - p = strtok(0, " :"); - if (stricmp(p, "?")) - name = String(p).Trim(); - else - name = ""; - // type - p = strtok(0, " "); - if (stricmp(p, "?")) - typeDef = String(p).Trim(); - else - typeDef = ""; - recN->procInfo->AddLocal(-offset, size, name, typeDef); - } - } - - ClearFlag(cfPass2, Adr2Pos(Adr)); - AnalyzeProc2(Adr, false, false); - AnalyzeArguments(Adr); - - // If virtual then propogate VMT names - // !!! prototype !!! - procName = ExtractProcName(recN->GetName()); - if (recN->procInfo->flags & PF_VIRTUAL) { - cnt = recN->xrefs->Count; - for (n = 0; n < cnt; n++) { - recX = (PXrefRec)recN->xrefs->Items[n]; - if (recX->type == 'D') { - recN1 = GetInfoRec(recX->adr); - ofs = GetMethodOfs(recN1, Adr); - if (ofs != -1) { - // Down (to root) - adr = recX->adr; - rootAdr = adr; - while (adr) { - recM = GetMethodInfo(adr, 'V', ofs); - if (recM) - rootAdr = adr; - adr = GetParentAdr(adr); - } - // Up (all classes that inherits rootAdr) - for (m = 0; m < VmtList->Count; m++) { - recV = (PVmtListRec)VmtList->Items[m]; - if (IsInheritsByAdr(recV->vmtAdr, rootAdr)) { - recM = GetMethodInfo(recV->vmtAdr, 'V', ofs); - if (recM) { - className = GetClsName(recV->vmtAdr); - recM->name = className + "." + procName; - if (recM->address != Adr && !recM->abstract) { - recN1 = GetInfoRec(recM->address); - if (!recN1->HasName()) - recN1->SetName(className + "." + procName); - else { - dotpos = recN1->GetName().Pos("."); - recN1->SetName(recN1->GetName().SubString(1, dotpos) + procName); - } - // recN1->name = className + "." + procName; - recN1->kind = recN->kind; - recN1->type = recN->type; - recN1->procInfo->flags |= PF_VIRTUAL; - recN1->procInfo->DeleteArgs(); - recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); - for (a = 1; a < recN->procInfo->args->Count; a++) { - argInfo = (PARGINFO) recN->procInfo->args->Items[a]; - recN1->procInfo->AddArg(argInfo); - } - } - } - } - } - } - } - } - } - - // DWORD adr = CurProcAdr; - - // Edit current proc - if (Adr == CurProcAdr) { - RedrawCode(); - // Current proc from current unit - if (recU->fromAdr == CurUnitAdr) - ShowUnitItems(recU, lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - } - else { - ShowUnitItems(recU, lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - } - ProjectModified = true; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miEditFunctionCClick(TObject *Sender) { - EditFunction(CurProcAdr); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miMapGeneratorClick(TObject *Sender) { - String procName; - - String mapName = ""; - if (SourceFile != "") - mapName = ChangeFileExt(SourceFile, ".map"); - if (IDPFile != "") - mapName = ChangeFileExt(IDPFile, ".map"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "MAP|*.map"; - SaveDlg->FileName = mapName; - - if (!SaveDlg->Execute()) - return; - - mapName = SaveDlg->FileName; - if (FileExists(mapName)) { - if (Application->MessageBox(L"File already exists. Overwrite?", L"Warning", MB_YESNO) == IDNO) - return; - } - - Screen->Cursor = crHourGlass; - FILE *fMap = fopen(AnsiString(mapName).c_str(), "wt+"); - if (!fMap) { - ShowMessage("Cannot open map file"); - return; - } - fprintf(fMap, "\n Start Length Name Class\n"); - fprintf(fMap, " 0001:00000000 %09XH CODE CODE\n", CodeSize); - fprintf(fMap, "\n\n Address Publics by Value\n\n"); - - for (int n = 0; n < CodeSize; n++) { - if (IsFlagSet(cfProcStart, n) && !IsFlagSet(cfEmbedded, n)) { - int adr = Pos2Adr(n); - PInfoRec recN = GetInfoRec(adr); - if (recN) { - if (adr != EP) { - PUnitRec recU = GetUnit(adr); - if (recU) { - String moduleName = GetUnitName(recU); - if (adr == recU->iniadr) - procName = "Initialization"; - else if (adr == recU->finadr) - procName = "Finalization"; - else - procName = recN->MakeMapName(adr); - - fprintf(fMap, " 0001:%08X %s.%s\n", n, moduleName.c_str(), procName.c_str()); - } - else { - procName = recN->MakeMapName(adr); - fprintf(fMap, " 0001:%08X %s\n", n, procName.c_str()); - } - // if (!IsFlagSet(cfImport, n)) - // { - // fprintf(fMap, "%lX %s\n", adr, recN->MakePrototype(adr, true, true, false, true, false).c_str()); - // } - } - else { - fprintf(fMap, " 0001:%08X EntryPoint\n", n); - } - } - } - } - - fprintf(fMap, "\nProgram entry point at 0001:%08X\n", EP - CodeBase); - fclose(fMap); - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCommentsGeneratorClick(TObject *Sender) { - String line; - - String txtName = ""; - if (SourceFile != "") - txtName = ChangeFileExt(SourceFile, ".txt"); - if (IDPFile != "") - txtName = ChangeFileExt(IDPFile, ".txt"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "TXT|*.txt"; - SaveDlg->FileName = txtName; - - if (!SaveDlg->Execute()) - return; - - txtName = SaveDlg->FileName; - - if (FileExists(txtName)) { - if (Application->MessageBox(L"File already exists. Overwrite?", L"Warning", MB_YESNO) == IDNO) - return; - } - - Screen->Cursor = crHourGlass; - - FILE* lstF = fopen(AnsiString(txtName).c_str(), "wt+"); - /* - for (int n = 0; n < CodeSize; n++) - { - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->picode) fprintf(lstF, "C %08lX %s\n", CodeBase + n, MakeComment(recN->picode).c_str()); - } - */ - for (int n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - if (recU->kb || recU->trivial) - continue; - - for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) { - if (adr == recU->finadr) { - if (!recU->trivialFin) - OutputCode(lstF, adr, "", true); - continue; - } - if (adr == recU->iniadr) { - if (!recU->trivialIni) - OutputCode(lstF, adr, "", true); - continue; - } - - int pos = Adr2Pos(adr); - PInfoRec recN = GetInfoRec(adr); - if (!recN) - continue; - - BYTE kind = recN->kind; - - if (kind == ikProc || kind == ikFunc || kind == ikConstructor || kind == ikDestructor) { - OutputCode(lstF, adr, "", true); - continue; - } - - if (IsFlagSet(cfProcStart, pos)) { - if (recN->kind == ikConstructor) { - OutputCode(lstF, adr, "", true); - } - else if (recN->kind == ikDestructor) { - OutputCode(lstF, adr, "", true); - } - else - OutputCode(lstF, adr, "", true); - } - } - } - fclose(lstF); - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miIDCGeneratorClick(TObject *Sender) { - String idcName = "", idcTemplate = ""; - if (SourceFile != "") { - idcName = ChangeFileExt(SourceFile, ".idc"); - idcTemplate = ChangeFileExt(SourceFile, ""); - } - if (IDPFile != "") { - idcName = ChangeFileExt(IDPFile, ".idc"); - idcTemplate = ChangeFileExt(IDPFile, ""); - } - - TSaveIDCDialog* SaveIDCDialog = new TSaveIDCDialog(this, "SAVEIDCDLG"); - SaveIDCDialog->InitialDir = WrkDir; - SaveIDCDialog->Filter = "IDC|*.idc"; - SaveIDCDialog->FileName = idcName; - - if (!SaveIDCDialog->Execute()) - return; - - idcName = SaveIDCDialog->FileName; - delete SaveIDCDialog; - - if (FileExists(idcName)) { - if (Application->MessageBox(L"File already exists. Overwrite?", L"Warning", MB_YESNO) == IDNO) - return; - } - - if (SplitIDC) { - if (FIdcSplitSize->ShowModal() == mrCancel) - return; - } - - Screen->Cursor = crHourGlass; - - FILE* idcF = fopen(AnsiString(idcName).c_str(), "wt+"); - TIDCGen *idcGen = new TIDCGen(idcF, SplitSize); - - idcGen->OutputHeaderFull(); - - int pos, curSize; - - for (pos = 0, curSize = 0; pos < TotalSize; pos++) { - PInfoRec recN = GetInfoRec(Pos2Adr(pos)); - if (!recN) - continue; - - if (SplitIDC && idcGen->CurrentBytes >= SplitSize) { - fprintf(idcF, "}"); - fclose(idcF); - idcName = idcTemplate + "_" + idcGen->CurrentPartNo + ".idc"; - idcF = fopen(AnsiString(idcName).c_str(), "wt+"); - idcGen->NewIDCPart(idcF); - idcGen->OutputHeaderShort(); - } - - BYTE kind = recN->kind; - BYTE len; - - if (IsFlagSet(cfRTTI, pos)) { - PUnitRec recU = GetUnit(Pos2Adr(pos)); - if (!recU) - continue; - - if (recU->names->Count == 1) - idcGen->unitName = recU->names->Strings[0]; - else - idcGen->unitName = ".Unit" + String(recU->iniOrder); - - switch (kind) { - case ikInteger: // 1 - idcGen->OutputRTTIInteger(kind, pos); - break; - case ikChar: // 2 - idcGen->OutputRTTIChar(kind, pos); - break; - case ikEnumeration: // 3 - idcGen->OutputRTTIEnumeration(kind, pos, Pos2Adr(pos)); - break; - case ikFloat: // 4 - idcGen->OutputRTTIFloat(kind, pos); - break; - case ikString: // 5 - idcGen->OutputRTTIString(kind, pos); - break; - case ikSet: // 6 - idcGen->OutputRTTISet(kind, pos); - break; - case ikClass: // 7 - idcGen->OutputRTTIClass(kind, pos); - break; - case ikMethod: // 8 - idcGen->OutputRTTIMethod(kind, pos); - break; - case ikWChar: // 9 - idcGen->OutputRTTIWChar(kind, pos); - break; - case ikLString: // 0xA - idcGen->OutputRTTILString(kind, pos); - break; - case ikWString: // 0xB - idcGen->OutputRTTIWString(kind, pos); - break; - case ikVariant: // 0xC - idcGen->OutputRTTIVariant(kind, pos); - break; - case ikArray: // 0xD - idcGen->OutputRTTIArray(kind, pos); - break; - case ikRecord: // 0xE - idcGen->OutputRTTIRecord(kind, pos); - break; - case ikInterface: // 0xF - idcGen->OutputRTTIInterface(kind, pos); - break; - case ikInt64: // 0x10 - idcGen->OutputRTTIInt64(kind, pos); - break; - case ikDynArray: // 0x11 - idcGen->OutputRTTIDynArray(kind, pos); - break; - case ikUString: // 0x12 - idcGen->OutputRTTIUString(kind, pos); - break; - case ikClassRef: // 0x13 - idcGen->OutputRTTIClassRef(kind, pos); - break; - case ikPointer: // 0x14 - idcGen->OutputRTTIPointer(kind, pos); - break; - case ikProcedure: // 0x15 - idcGen->OutputRTTIProcedure(kind, pos); - break; - } - continue; - } - if (kind == ikVMT) { - idcGen->OutputVMT(pos, recN); - continue; - } - if (kind == ikString) { - idcGen->MakeShortString(pos); - continue; - } - if (kind == ikLString) { - idcGen->MakeLString(pos); - continue; - } - if (kind == ikWString) { - idcGen->MakeWString(pos); - continue; - } - if (kind == ikUString) { - idcGen->MakeUString(pos); - continue; - } - if (kind == ikCString) { - idcGen->MakeCString(pos); - continue; - } - if (kind == ikResString) { - idcGen->OutputResString(pos, recN); - continue; - } - if (kind == ikGUID) { - idcGen->MakeArray(pos, 16); - continue; - } - if (kind == ikData) { - idcGen->OutputData(pos, recN); - continue; - } - if (IsFlagSet(cfProcStart, pos)) { - pos += idcGen->OutputProc(pos, recN, IsFlagSet(cfImport, pos)); - } - } - fprintf(idcF, "}"); - fclose(idcF); - delete idcGen; - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmUnitsPopup(TObject *Sender) { - if (lbUnits->ItemIndex < 0) - return; - - String item = lbUnits->Items->Strings[lbUnits->ItemIndex]; - DWORD adr; - sscanf(AnsiString(item).c_str() + 1, "%lX", &adr); - PUnitRec recU = GetUnit(adr); - miRenameUnit->Enabled = (!recU->kb && recU->names->Count <= 1); -} - -// --------------------------------------------------------------------------- -// MXXXXXXXXM COP Op1, Op2, Op3;commentF -// XXXXXXXX - address -// F - flags (1:cfLoc; 2:cfSkip; 4:cfLoop; 8:jmp or jcc -void __fastcall TFMain_11011981::lbCodeDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { - bool ib; - BYTE _f, _db; - int n, flags, _instrlen, _textLen, _len, _sWid, _cPos, _offset, _ap; - int _dbPos, _ddPos; - DWORD _adr, _val, _dd; - TColor _color; - TListBox *lb; - TCanvas *canvas; - String text, _item, _comment; - PInfoRec _recN; - DISINFO _disInfo; - - // After closing Project we cannot execute this handler (Code = 0) - if (!Image) - return; - - lb = (TListBox*)Control; - canvas = lb->Canvas; - - if (Index < lb->Count) { - flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); - if (!Control->UseRightToLeftAlignment()) - Rect.Left += 2; - else - Rect.Right -= 2; - - text = lb->Items->Strings[Index]; - _textLen = text.Length(); - // lb->ItemHeight = canvas->TextHeight("T"); - - // First row (name of procedure with prototype) output without highlighting - if (!Index) { - Rect.Right = Rect.Left; - DrawOneItem(text, canvas, Rect, 0, flags); - return; - } - // F - _f = text[_textLen]; - canvas->Brush->Color = TColor(0xFFFFFF); - if (State.Contains(odSelected)) - canvas->Brush->Color = TColor(0xFFFFC0); - else if (_f & 2) // skip - canvas->Brush->Color = TColor(0xF5F5FF); - canvas->FillRect(Rect); - - // Width of space - _sWid = canvas->TextWidth(" "); - // Comment position - _cPos = text.Pos(";"); - // Sign for > (blue) - _item = text.SubString(1, 1); - Rect.Right = Rect.Left; - DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); - - // Address (loop is blue, loc is black, others are light gray) - _item = text.SubString(2, 8); - _adr = StrToInt(String("$") + _item); - // loop or loc - if (_f & 5) - _color = TColor(0xFF8080); - else - _color = TColor(0xBBBBBB); // LightGray - DrawOneItem(_item, canvas, Rect, _color, flags); - - // Sign for > (blue) - _item = text.SubString(10, 1); - DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); - - // Data (case or exeption table) - _dbPos = text.Pos(" db "); - _ddPos = text.Pos(" dd "); - if (_dbPos || _ddPos) { - Rect.Right += 7 * _sWid; - if (_dbPos) { - DrawOneItem("db", canvas, Rect, TColor(0), flags); - // Spaces after db - Rect.Right += (ASMMAXCOPLEN - 2) * _sWid; - _db = *(Code + Adr2Pos(_adr)); - DrawOneItem(Val2Str0((DWORD)_db), canvas, Rect, TColor(0xFF8080), flags); - } - else if (_ddPos) { - DrawOneItem("dd", canvas, Rect, TColor(0), flags); - // Spaces after dd - Rect.Right += (ASMMAXCOPLEN - 2) * _sWid; - _dd = *((DWORD*)(Code + Adr2Pos(_adr))); - DrawOneItem(Val2Str8(_dd), canvas, Rect, TColor(0xFF8080), flags); - } - // Comment (light gray) - if (_cPos) { - _item = text.SubString(_cPos, _textLen); - _item.SetLength(_item.Length() - 1); - DrawOneItem(_item, canvas, Rect, TColor(0xBBBBBB), flags); - } - return; - } - // Get instruction tokens - Disasm.Disassemble(Code + Adr2Pos(_adr), (__int64)_adr, &_disInfo, 0); - // repprefix - _len = 0; - if (_disInfo.RepPrefix != -1) { - _item = RepPrefixTab[_disInfo.RepPrefix]; - _len = _item.Length(); - } - Rect.Right += (6 - _len) * _sWid; - if (_disInfo.RepPrefix != -1) { - DrawOneItem(_item, canvas, Rect, TColor(0), flags); - } - Rect.Right += _sWid; - - // Cop (black, if float then green) - _item = String(_disInfo.Mnem); - _len = _item.Length(); - if (!_disInfo.Float) - _color = TColor(0); - else - _color = TColor(0x808000); - if (!SameText(_item, "movs")) { - DrawOneItem(_item, canvas, Rect, _color, flags); - // Operands - if (_disInfo.OpNum) { - Rect.Right += (ASMMAXCOPLEN - _len) * _sWid; - for (n = 0; n < _disInfo.OpNum; n++) { - if (n) - DrawOneItem(",", canvas, Rect, TColor(0), flags); - - ib = (_disInfo.BaseReg != -1 || _disInfo.IndxReg != -1); - _offset = _disInfo.Offset; - // Op1 - if (_disInfo.OpType[n] == otIMM) { - _val = _disInfo.Immediate; - _ap = Adr2Pos(_val); - _color = TColor(0xFF8080); - if (_ap >= 0 && (_disInfo.Call || _disInfo.Branch)) { - _recN = GetInfoRec(_val); - if (_recN && _recN->HasName()) { - _item = _recN->GetName(); - _color = TColor(0xC08000); - } - else - _item = Val2Str8(_val); - } - else { - if (_val <= 9) - _item = String(_val); - else { - _item = Val2Str0(_val); - if (!isdigit(_item[1])) - _item = "0" + _item; - } - } - DrawOneItem(_item, canvas, Rect, _color, flags); - } - else if (_disInfo.OpType[n] == otREG || _disInfo.OpType[n] == otFST) { - _item = GetAsmRegisterName(_disInfo.OpRegIdx[n]); - DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); - } - else if (_disInfo.OpType[n] == otMEM) { - if (_disInfo.OpSize) { - _item = String(_disInfo.sSize) + " ptr "; - DrawOneItem(_item, canvas, Rect, TColor(0), flags); - } - if (_disInfo.SegPrefix != -1) { - _item = String(SegRegTab[_disInfo.SegPrefix]); - DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); - DrawOneItem(":", canvas, Rect, TColor(0), flags); - } - DrawOneItem("[", canvas, Rect, TColor(0), flags); - if (ib) { - if (_disInfo.BaseReg != -1) { - _item = GetAsmRegisterName(_disInfo.BaseReg); - DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); - } - if (_disInfo.IndxReg != -1) { - if (_disInfo.BaseReg != -1) { - DrawOneItem("+", canvas, Rect, TColor(0), flags); - } - _item = GetAsmRegisterName(_disInfo.IndxReg); - DrawOneItem(_item, canvas, Rect, TColor(0x0000B0), flags); - if (_disInfo.Scale != 1) { - DrawOneItem("*", canvas, Rect, TColor(0), flags); - _item = String(_disInfo.Scale); - DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); - } - } - if (_offset) { - if (_offset < 0) { - _item = "-"; - _offset = -_offset; - } - else { - _item = "+"; - } - DrawOneItem(_item, canvas, Rect, TColor(0), flags); - if (_offset < 9) - _item = String(_offset); - else { - _item = Val2Str0(_offset); - if (!isdigit(_item[1])) - _item = "0" + _item; - } - DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); - } - } - else { - if (_offset < 0) - _offset = -_offset; - if (_offset < 9) - _item = String(_offset); - else { - _item = Val2Str0(_offset); - if (!isdigit(_item[1])) - _item = "0" + _item; - } - DrawOneItem(_item, canvas, Rect, TColor(0xFF8080), flags); - } - DrawOneItem("]", canvas, Rect, TColor(0), flags); - } - } - } - } - // movsX - else { - _item += String(_disInfo.sSize[0]); - DrawOneItem(_item, canvas, Rect, _color, flags); - } - // Comment (light gray) - if (_cPos) { - _item = text.SubString(_cPos, _textLen); - _item.SetLength(_item.Length() - 1); - DrawOneItem(_item, canvas, Rect, TColor(0xBBBBBB), flags); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miListerClick(TObject *Sender) { - bool imp, emb; - String line; - - String lstName = ""; - if (SourceFile != "") - lstName = ChangeFileExt(SourceFile, ".lst"); - if (IDPFile != "") - lstName = ChangeFileExt(IDPFile, ".lst"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "LST|*.lst"; - SaveDlg->FileName = lstName; - - if (!SaveDlg->Execute()) - return; - - lstName = SaveDlg->FileName; - - if (FileExists(lstName)) { - if (Application->MessageBox(L"File already exists. Overwrite?", L"Warning", MB_YESNO) == IDNO) - return; - } - - Screen->Cursor = crHourGlass; - - FILE* lstF = fopen(AnsiString(lstName).c_str(), "wt+"); - for (int n = 0; n < UnitsNum; n++) { - PUnitRec recU = (PUnitRec)Units->Items[n]; - if (recU->kb || recU->trivial) - continue; - fprintf(lstF, "//===========================================================================\n"); - fprintf(lstF, "//Unit%03d", recU->iniOrder); - if (recU->names->Count) - fprintf(lstF, " (%s)", recU->names->Strings[0]); - fprintf(lstF, "\n"); - - for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) { - if (adr == recU->finadr) { - if (!recU->trivialFin) { - OutputCode(lstF, adr, "procedure Finalization;", false); - } - continue; - } - if (adr == recU->iniadr) { - if (!recU->trivialIni) { - OutputCode(lstF, adr, "procedure Initialization;", false); - } - continue; - } - - int pos = Adr2Pos(adr); - PInfoRec recN = GetInfoRec(adr); - if (!recN) - continue; - - imp = emb = false; - BYTE kind = recN->kind; - if (IsFlagSet(cfProcStart, pos)) { - imp = IsFlagSet(cfImport, pos); - emb = (recN->procInfo->flags & PF_EMBED); - } - - if (kind == ikUnknown) - continue; - - if (kind > ikUnknown && kind <= ikProcedure && recN->HasName()) { - if (kind == ikEnumeration || kind == ikSet) { - line = FTypeInfo_11011981->GetRTTI(adr); - fprintf(lstF, "%s = %s;\n", recN->GetName(), line); - } - else - fprintf(lstF, "%08lX <%s> %s\n", adr, TypeKind2Name(kind), recN->GetName()); - continue; - } - - if (kind == ikResString) { - fprintf(lstF, "%08lX %s=%s\n", adr, recN->GetName(), recN->rsInfo->value); - continue; - } - - if (kind == ikVMT) { - fprintf(lstF, "%08lX %s\n", adr, recN->GetName()); - continue; - } - - if (kind == ikGUID) { - fprintf(lstF, "%08lX %s\n", adr, Guid2String(Code + pos)); - continue; - } - - if (kind == ikConstructor) { - OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); - continue; - } - - if (kind == ikDestructor) { - OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); - continue; - } - - if (kind == ikProc) { - line = ""; - if (imp) - line += "import "; - else if (emb) - line += "embedded "; - line += recN->MakePrototype(adr, true, false, false, true, false); - OutputCode(lstF, adr, line, false); - continue; - } - - if (kind == ikFunc) { - line = ""; - if (imp) - line += "import "; - else if (emb) - line += "embedded "; - line += recN->MakePrototype(adr, true, false, false, true, false); - OutputCode(lstF, adr, line, false); - continue; - } - - if (IsFlagSet(cfProcStart, pos)) { - if (kind == ikDestructor) { - OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); - } - else if (kind == ikDestructor) { - OutputCode(lstF, adr, recN->MakePrototype(adr, true, false, false, true, false), false); - } - else { - line = ""; - if (emb) - line += "embedded "; - line += recN->MakePrototype(adr, true, false, false, true, false); - OutputCode(lstF, adr, line, false); - } - } - } - } - fclose(lstF); - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::OutputLine(FILE* OutF, BYTE flags, DWORD Adr, String Content) { - // Ouput comments - if (flags & 0x10) { - char *p = strchr(AnsiString(Content).c_str(), ';'); - if (p) - fprintf(OutF, "C %08lX %s\n", Adr, p + 1); - return; - } - - // Jump direction - if (flags & 4) - fprintf(OutF, "<"); - else if (flags & 8) - fprintf(OutF, ">"); - else - fprintf(OutF, " "); - /* - if (flags & 1) - fprintf(OutF, "%08lX\n", Adr); - else - fprintf(OutF, " "); - */ - fprintf(OutF, "%08lX %s\n", Adr, Content.c_str()); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::OutputCode(FILE* outF, DWORD fromAdr, String prototype, bool onlyComments) { - BYTE op, flags; - int row = 0, num, instrLen, instrLen1, instrLen2; - DWORD Adr, Adr1, Pos, lastMovAdr = 0; - int fromPos, curPos, _procSize, _ap, _pos, _idx; - DWORD curAdr; - DWORD lastAdr = 0; - PInfoRec recN, recN1; - String line; - DISINFO DisInfo, DisInfo1; - char disLine[100]; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return; - - recN = GetInfoRec(fromAdr); - int outRows = MAX_DISASSEMBLE; - if (IsFlagSet(cfImport, fromPos)) - outRows = 1; - - if (!onlyComments && prototype != "") { - fprintf(outF, "//---------------------------------------------------------------------------\n"); - fprintf(outF, "//%s\n", prototype); - } - _procSize = GetProcSize(fromAdr); - curPos = fromPos; - curAdr = fromAdr; - - while (row < outRows) { - // End of procedure - if (curAdr != fromAdr && _procSize && curAdr - fromAdr >= _procSize) - break; - flags = 0; - // Only comments? - if (onlyComments) - flags |= 0x10; - // Loc? - if (IsFlagSet(cfLoc, curPos)) - flags |= 1; - // Skip? - if (IsFlagSet(cfSkip | cfDSkip, curPos)) - flags |= 2; - - // If exception table, output it - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - OutputLine(outF, flags, curAdr, "dd " + String(num)); - row++; - curPos += 4; - curAdr += 4; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Adr = *((DWORD*)(Code + curPos)); - line = "dd " + Val2Str8(Adr); - // Name of Exception - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) - line += ";" + recN->GetName(); - } - OutputLine(outF, flags, curAdr, line); - row++; - - // dd offset ExceptionProc - curPos += 4; - curAdr += 4; - Adr = *((DWORD*)(Code + curPos)); - OutputLine(outF, flags, curAdr, "dd " + Val2Str8(Adr)); - row++; - - curPos += 4; - curAdr += 4; - } - continue; - } - - BYTE b1 = Code[curPos]; - BYTE b2 = Code[curPos + 1]; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, disLine); - if (!instrLen) { - OutputLine(outF, flags, curAdr, "???"); - row++; - curPos++; - curAdr++; - continue; - } - op = Disasm.GetOp(DisInfo.Mnem); - - // Check inside instruction Fixup or ThreadVar - bool NameInside = false; - DWORD NameInsideAdr; - for (int k = 1; k < instrLen; k++) { - if (Infos[curPos + k]) { - NameInside = true; - NameInsideAdr = curAdr + k; - break; - } - } - - line = String(disLine); - - if (curAdr >= lastAdr) - lastAdr = 0; - - // Proc end - if (DisInfo.Ret && (!lastAdr || curAdr == lastAdr)) { - OutputLine(outF, flags, curAdr, line); - row++; - break; - } - - if (op == OP_MOV) - lastMovAdr = DisInfo.Offset; - - if (b1 == 0xEB || // short relative abs jmp or cond jmp - (b1 >= 0x70 && b1 <= 0x7F) || (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - if (op == OP_JMP) { - _ap = Adr2Pos(Adr); - recN = GetInfoRec(Adr); - if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) { - line = "jmp " + recN->GetName(); - } - } - flags |= 8; - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - OutputLine(outF, flags, curAdr, line); - row++; - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (b1 == 0xE9) // relative abs jmp or cond jmp - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - _ap = Adr2Pos(Adr); - recN = GetInfoRec(Adr); - if (recN && IsFlagSet(cfProcStart, _ap) && recN->HasName()) { - line = "jmp " + recN->GetName(); - } - flags |= 8; - if (!recN && Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - OutputLine(outF, flags, curAdr, line); - row++; - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (DisInfo.Call) // call sub_XXXXXXXX - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN && recN->HasName()) { - line = "call " + recN->GetName(); - // Found @Halt0 - exit - if (recN->SameName("@Halt0") && fromAdr == EP && !lastAdr) { - OutputLine(outF, flags, curAdr, line); - row++; - break; - } - } - } - recN = GetInfoRec(curAdr); - if (recN && recN->picode) - line += ";" + MakeComment(recN->picode); - OutputLine(outF, flags, curAdr, line); - row++; - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) - // near absolute indirect jmp (Case) - { - OutputLine(outF, flags, curAdr, line); - row++; - if (!IsValidCodeAdr(DisInfo.Offset)) - break; - /* - //First instruction - if (curAdr == fromAdr) break; - */ - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Table address - last 4 bytes of instruction - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Analyze address range to find table cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // If exist cTblAdr, skip this table - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - for (int k = 0; k < CNum; k++) { - BYTE db = Code[Pos]; - CTab[k] = db; - OutputLine(outF, flags, curAdr, "db " + String(db)); - row++; - Pos++; - Adr++; - } - } - // Check transitions by negative register values (in Delphi 2009) - // bool neg = false; - // Adr1 = *((DWORD*)(Code + Pos - 4)); - // if (IsValidCodeAdr(Adr1) && IsFlagSet(cfLoc, Adr2Pos(Adr1))) neg = true; - - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - - // Add row to assembler listing - OutputLine(outF, flags, curAdr, "dd " + Val2Str8(Adr1)); - row++; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - // ---------------------------------- - // PosTry: xor reg, reg - // push ebp - // push offset @1 - // push fs:[reg] - // mov fs:[reg], esp - // ... - // @2: ... - // At @1 various variants: - // ---------------------------------- - // @1: jmp @HandleFinally - // jmp @2 - // ---------------------------------- - // @1: jmp @HandleAnyException - // call DoneExcept - // ---------------------------------- - // @1: jmp HandleOnException - // dd num - // Äàëåå òàáëèöà èç num çàïèñåé âèäà - // dd offset ExceptionInfo - // dd offset ExceptionProc - // ---------------------------------- - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN = GetInfoRec(DisInfo.Immediate); - if (recN) { - if (recN->SameName("@HandleFinally")) { - // jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - /* - //@2 - Adr1 = DisInfo.Immediate - 4; - Adr = *((DWORD*)(Code + Adr2Pos(Adr1))); - if (IsValidCodeAdr(Adr) && Adr > lastAdr) lastAdr = Adr; - */ - } - else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // Set flag cfETable to correct output data - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Pos += 4; - // dd offset ExceptionProc - Pos += 4; - } - } - } - } - } - } - OutputLine(outF, flags, curAdr, line); - row++; - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - // Name inside instruction (Fixip, ThreadVar) - String namei = "", comment = "", name, pname, type, ptype; - if (NameInside) { - recN = GetInfoRec(NameInsideAdr); - if (recN && recN->HasName()) { - namei += recN->GetName(); - if (recN->type != "") - namei += ":" + recN->type; - } - } - // comment - recN = GetInfoRec(curAdr); - if (recN && recN->picode) - comment = MakeComment(recN->picode); - - DWORD targetAdr = 0; - if (IsValidImageAdr(DisInfo.Immediate)) { - if (!IsValidImageAdr(DisInfo.Offset)) - targetAdr = DisInfo.Immediate; - } - else if (IsValidImageAdr(DisInfo.Offset)) - targetAdr = DisInfo.Offset; - - if (targetAdr) { - name = pname = type = ptype = ""; - _pos = Adr2Pos(targetAdr); - if (_pos >= 0) { - recN = GetInfoRec(targetAdr); - if (recN) { - if (recN->kind == ikResString) { - name = recN->GetName() + ":PResStringRec"; - } - else { - if (recN->HasName()) { - name = recN->GetName(); - if (recN->type != "") - type = recN->type; - } - else if (IsFlagSet(cfProcStart, _pos)) - name = GetDefaultProcName(targetAdr); - } - } - // For Delphi2 pointers to VMT are distinct - else if (DelphiVersion == 2) { - recN = GetInfoRec(targetAdr + VmtSelfPtr); - if (recN && recN->kind == ikVMT && recN->HasName()) { - name = recN->GetName(); - } - } - Adr = *((DWORD*)(Code + _pos)); - if (IsValidImageAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN) { - if (recN->HasName()) { - pname = recN->GetName(); - ptype = recN->type; - } - else if (IsFlagSet(cfProcStart, _pos)) - pname = GetDefaultProcName(Adr); - } - } - } - else { - _idx = BSSInfos->IndexOf(Val2Str8(targetAdr)); - if (_idx != -1) { - recN = (PInfoRec)BSSInfos->Objects[_idx]; - name = recN->GetName(); - type = recN->type; - } - } - } - if (SameText(comment, name)) - name = ""; - if (pname != "") { - if (comment != "") - comment += " "; - comment += "^" + pname; - if (ptype != "") - comment += ":" + ptype; - } - else if (name != "") { - if (comment != "") - comment += " "; - comment += name; - if (type != "") - comment += ":" + type; - } - - if (comment != "" || namei != "") { - line += ";"; - if (comment != "") - line += comment; - if (namei != "") - line += "{" + namei + "}"; - } - if (line.Length() > MAXLEN) - line = line.SubString(1, MAXLEN) + "..."; - OutputLine(outF, flags, curAdr, line); - row++; - curPos += instrLen; - curAdr += instrLen; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::wm_dropFiles(TWMDropFiles& msg) { - TFileDropper* fc = new TFileDropper((HDROP)msg.Drop); - try { - for (int i = 0; i < fc->FileCount; ++i) { - String droppedFile = fc->Files[i]; - String ext = ExtractFileExt(droppedFile).LowerCase(); - - if (SameText(ext, ".lnk")) - DoOpenDelphiFile(DELHPI_VERSION_AUTO, GetFilenameFromLink(droppedFile), true, true); - else if (SameText(ext, ".idp") && miOpenProject->Enabled) - DoOpenProjectFile(droppedFile); - else if ((SameText(ext, ".exe") || SameText(ext, ".bpl") || SameText(ext, ".dll") || SameText(ext, ".scr")) && miLoadFile->Enabled) - DoOpenDelphiFile(DELHPI_VERSION_AUTO, droppedFile, true, true); - - // Processed the first - and go out - we cannot process more than one file yet - break; - } - // TPoint ptDrop = fc->DropPoint; - } - catch (...) { - } - delete fc; - msg.Result = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miAboutClick(TObject *Sender) { - FAboutDlg_11011981->ShowModal(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miHelpClick(TObject *Sender) { - ShellExecute(Handle, AnsiString("open").c_str(), AnsiString(Application->HelpFile).c_str(), 0, 0, 1); -} -// --------------------------------------------------------------------------- -// #include "TabUnits.cpp" -// #include "TabRTTIs.cpp" -// #include "TabStrings.cpp" -// #include "TabNames.cpp" -// #include "CXrefs.cpp" -// #include "Analyze1.cpp" -// #include "Analyze2.cpp" -// #include "AnalyzeArguments.cpp" - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::FormCloseQuery(TObject *Sender, bool &CanClose) { - int _res; - - if (AnalyzeThread) { - AnalyzeThread->Suspend(); - String sbtext0 = FProgressBar->sb->Panels->Items[0]->Text; - String sbtext1 = FProgressBar->sb->Panels->Items[1]->Text; - FProgressBar->Visible = false; - - _res = Application->MessageBox(L"Analysis is not yet completed. Do You really want to exit IDR?", L"Confirmation", MB_YESNO); - if (_res == IDNO) { - FProgressBar->Visible = true; - FProgressBar->sb->Panels->Items[0]->Text = sbtext0; - FProgressBar->sb->Panels->Items[1]->Text = sbtext1; - FProgressBar->Update(); - - AnalyzeThread->Resume(); - CanClose = false; - return; - } - AnalyzeThread->Terminate(); - } - - if (ProjectLoaded && ProjectModified) { - _res = Application->MessageBox(L"Save active Project?", L"Confirmation", MB_YESNOCANCEL); - if (_res == IDCANCEL) { - CanClose = false; - return; - } - if (_res == IDYES) { - if (IDPFile == "") - IDPFile = ChangeFileExt(SourceFile, ".idp"); - - SaveDlg->InitialDir = WrkDir; - SaveDlg->Filter = "IDP|*.idp"; - SaveDlg->FileName = IDPFile; - - if (!SaveDlg->Execute()) { - CanClose = false; - return; - } - SaveProject(SaveDlg->FileName); - } - CloseProject(); - } - - IniFileWrite(); - - CanClose = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCtdPasswordClick(TObject *Sender) { - BYTE op; - DWORD curPos, curAdr; - int instrLen, pwdlen = 0, beg; - String pwds = ""; - BYTE pwd[256]; - DISINFO DisInfo; - - PInfoRec recN = GetInfoRec(CtdRegAdr); - if (recN->xrefs->Count != 1) - return; - PXrefRec recX = (PXrefRec)recN->xrefs->Items[0]; - - int ofs; - for (ofs = recX->offset; ofs >= 0; ofs--) { - if (IsFlagSet(cfPush, Adr2Pos(recX->adr) + ofs)) - break; - } - /* - curPos = Adr2Pos(recX->adr) + ofs; - curAdr = Pos2Adr(curPos); - //pwdlen - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo); - pwdlen = DisInfo.Immediate + 1; - curPos += instrLen; curAdr += instrLen; - //pwd - beg = 128; - for (int n = 0; n < pwdlen;) - { - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo); - op = Disasm.GetOp(DisInfo.Mnem); - //mov [ebp-Ofs], B - if (op == OP_MOV && DisInfo.Op1Type == otMEM && DisInfo.Op2Type == otIMM && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) - { - ofs = DisInfo.Offset; if (128 + ofs < beg) beg = 128 + ofs; - pwd[128 + ofs] = DisInfo.Immediate; - n++; - } - curPos += instrLen; curAdr += instrLen; - } - for (int n = beg; n < beg + pwdlen; n++) - { - pwds += Val2Str2(pwd[n]); - } - */ - PROCHISTORYREC rec; - - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(recX->adr, recX->adr + ofs, -1, -1); - CodeHistoryPush(&rec); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmCodePanelPopup(TObject *Sender) { - miEmptyHistory->Enabled = (CodeHistoryPtr > 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miEmptyHistoryClick(TObject *Sender) { - memmove(&CodeHistory[0], &CodeHistory[CodeHistoryPtr], sizeof(PROCHISTORYREC)); - CodeHistoryPtr = 0; - CodeHistoryMax = CodeHistoryPtr; -} - -// --------------------------------------------------------------------------- -PFIELDINFO __fastcall GetClassField(String TypeName, int Offset) { - int n, Ofs1, Ofs2; - DWORD classAdr, prevClassAdr = 0; - PInfoRec recN; - PFIELDINFO fInfo1, fInfo2; - - classAdr = GetClassAdr(TypeName); - while (classAdr && Offset < GetClassSize(classAdr)) { - prevClassAdr = classAdr; - classAdr = GetParentAdr(classAdr); - } - classAdr = prevClassAdr; - if (classAdr) { - recN = GetInfoRec(classAdr); - if (recN && recN->vmtInfo && recN->vmtInfo->fields) { - for (n = 0; n < recN->vmtInfo->fields->Count; n++) { - fInfo1 = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; - Ofs1 = fInfo1->Offset; - if (n == recN->vmtInfo->fields->Count - 1) { - Ofs2 = 0x7FFFFFFF; - } - else { - fInfo2 = (PFIELDINFO)recN->vmtInfo->fields->Items[n + 1]; - Ofs2 = fInfo2->Offset; - } - if (Offset >= Ofs1 && Offset < Ofs2) { - return fInfo1; - } - } - } - } - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall GetRecordField(String ARecType, int AOfs, String& name, String& type) { - BYTE _len, _numOps, _kind; - char *p, *ps; - WORD _dw; - WORD *_uses; - int n, _idx, _pos, _elNum, Ofs, Ofs1, Ofs2; - DWORD _typeAdr; - PTypeRec _recT; - MTypeInfo _tInfo; - String _str, _name, _typeName, _result = ""; - - if (ARecType == "") - return -1; - - name = ""; - type = ""; - - _pos = ARecType.LastDelimiter("."); - if (_pos > 1 && ARecType[_pos + 1] != ':') - ARecType = ARecType.SubString(_pos + 1, ARecType.Length()); - - // File - String _recFileName = FMain_11011981->WrkDir + "\\types.idr"; - FILE* _recFile = fopen(AnsiString(_recFileName).c_str(), "rt"); - if (_recFile) { - while (1) { - if (!fgets(StringBuf, 1024, _recFile)) - break; - _str = String(StringBuf); - if (_str.Pos(ARecType + "=") == 1) { - while (1) { - if (!fgets(StringBuf, 1024, _recFile)) - break; - _str = String(StringBuf); - if (_str.Pos("end;")) - break; - if (_str.Pos("//" + Val2Str0(AOfs))) { - _result = _str; - _pos = _result.LastDelimiter(";"); - if (_pos) - _result.SetLength(_pos - 1); - _pos = _str.Pos(":"); - if (_pos) { - name = _str.SubString(1, _pos - 1); - type = _str.SubString(_pos + 1, _str.Length()); - } - fclose(_recFile); - return AOfs; - } - } - } - } - fclose(_recFile); - } - int tries = 5; - while (tries >= 0) { - tries--; - // KB - _uses = KnowledgeBase.GetTypeUses(AnsiString(ARecType).c_str()); - _idx = KnowledgeBase.GetTypeIdxByModuleIds(_uses, AnsiString(ARecType).c_str()); - if (_uses) - delete[]_uses; - - if (_idx != -1) { - _idx = KnowledgeBase.TypeOffsets[_idx].NamId; - if (KnowledgeBase.GetTypeInfo(_idx, INFO_FIELDS, &_tInfo)) { - if (_tInfo.FieldsNum) { - p = _tInfo.Fields; - for (n = 0; n < _tInfo.FieldsNum; n++) { - ps = p; - p++; // scope - Ofs1 = *((int*)p); - p += 4; // offset - p += 4; // case - _len = *((WORD*)p); - p += _len + 3; // name - _len = *((WORD*)p); - p += _len + 3; // type - if (n == _tInfo.FieldsNum - 1) { - Ofs2 = 0x7FFFFFFF; - } - else { - Ofs2 = *((int*)(p + 1)); - } - if (AOfs >= Ofs1 && AOfs < Ofs2) { - p = ps; - p++; // scope - Ofs1 = *((int*)p); - p += 4; // offset - p += 4; // case - _len = *((WORD*)p); - p += 2; - name = String(p, _len); - p += _len + 1; - _len = *((WORD*)p); - p += 2; - type = String(p, _len); - return Ofs1; - } - } - } - else if (_tInfo.Decl != "") { - ARecType = _tInfo.Decl; - // Ofs = GetRecordField(_tInfo.Decl, AOfs, name, type); - // if (Ofs >= 0) - // return Ofs; - } - } - } - } - // RTTI - _recT = GetOwnTypeByName(ARecType); - if (_recT && _recT->kind == ikRecord) { - _pos = Adr2Pos(_recT->adr); - _pos += 4; // SelfPtr - _pos++; // TypeKind - _len = Code[_pos]; - _pos++; - _name = String((char*)(Code + _pos), _len); - _pos += _len; // Name - _pos += 4; // Size - _elNum = *((DWORD*)(Code + _pos)); - _pos += 4; - for (n = 0; n < _elNum; n++) { - _typeAdr = *((DWORD*)(Code + _pos)); - _pos += 4; - Ofs1 = *((DWORD*)(Code + _pos)); - _pos += 4; - if (n == _elNum - 1) - Ofs2 = 0x7FFFFFFF; - else - Ofs2 = *((DWORD*)(Code + _pos + 4)); - if (AOfs >= Ofs1 && AOfs < Ofs2) { - name = _name + ".f" + Val2Str0(Ofs1); - type = GetTypeName(_typeAdr); - return Ofs1; - } - - } - if (DelphiVersion >= 2010) { - // NumOps - _numOps = Code[_pos]; - _pos++; - for (n = 0; n < _numOps; n++) // RecOps - { - _pos += 4; - } - _elNum = *((DWORD*)(Code + _pos)); - _pos += 4; // RecFldCnt - - for (n = 0; n < _elNum; n++) { - _typeAdr = *((DWORD*)(Code + _pos)); - _pos += 4; - Ofs1 = *((DWORD*)(Code + _pos)); - _pos += 4; - _pos++; // Flags - _len = Code[_pos]; - _pos++; - _name = String((char*)(Code + _pos), _len); - _pos += _len; - // AttrData - _dw = *((WORD*)(Code + _pos)); - _pos += _dw; // ATR!! - - if (n == _elNum - 1) - Ofs2 = 0x7FFFFFFF; - else - Ofs2 = *((DWORD*)(Code + _pos + 4)); - - if (AOfs >= Ofs1 && AOfs < Ofs2) { - if (_name != "") - name = _name; - else - name = "f" + Val2Str0(Ofs1); - type = GetTypeName(_typeAdr); - return Ofs1; - } - } - } - } - return -1; -} - -// --------------------------------------------------------------------------- -int __fastcall TFMain_11011981::GetField(String TypeName, int Offset, String& name, String& type) { - int size, kind, ofs; - PFIELDINFO fInfo; - String _fname, _ftype, _type = TypeName; - - _fname = ""; - _ftype = ""; - - while (Offset >= 0) { - kind = GetTypeKind(_type, &size); - if (kind != ikVMT && kind != ikArray && kind != ikRecord && kind != ikDynArray) - break; - - if (kind == ikVMT) { - if (!Offset) - return 0; - fInfo = GetClassField(_type, Offset); - if (name != "") - name += "."; - if (fInfo->Name != "") - name += fInfo->Name; - else - name += "f" + IntToHex((int)Offset, 0); - type = fInfo->Type; - - _type = fInfo->Type; - Offset -= fInfo->Offset; - continue; - } - if (kind == ikRecord) { - ofs = GetRecordField(_type, Offset, _fname, _ftype); - if (ofs >= 0) { - if (name != "") - name += "."; - name += _fname; - type = _ftype; - - _type = _ftype; - Offset -= ofs; - } - continue; - } - if (kind == ikArray || kind == ikDynArray) { - break; - } - } - return Offset; -} - -// --------------------------------------------------------------------------- -PFIELDINFO __fastcall TFMain_11011981::GetField(String TypeName, int Offset, bool* vmt, DWORD* vmtAdr, String prefix) { - int n, idx, kind, size, Ofs, Ofs1, Ofs2, pos1, pos2; - DWORD classAdr; - BYTE *p, *ps; - WORD *uses, Len; - MTypeInfo atInfo; - MTypeInfo *tInfo = &atInfo; - PFIELDINFO fInfo, fInfo1, fInfo2; - - *vmt = false; - *vmtAdr = 0; - classAdr = GetClassAdr(TypeName); - if (IsValidImageAdr(classAdr)) { - *vmt = true; - *vmtAdr = classAdr; - DWORD prevClassAdr = 0; - while (classAdr && Offset < GetClassSize(classAdr)) { - prevClassAdr = classAdr; - classAdr = GetParentAdr(classAdr); - } - classAdr = prevClassAdr; - - if (classAdr) { - *vmtAdr = classAdr; - PInfoRec recN = GetInfoRec(classAdr); - if (recN && recN->vmtInfo && recN->vmtInfo->fields) { - if (recN->vmtInfo->fields->Count == 1) { - fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[0]; - if (Offset == fInfo->Offset) { - fInfo->Name = prefix + "." + fInfo->Name; - return fInfo; - } - return 0; - } - for (int n = 0; n < recN->vmtInfo->fields->Count; n++) { - fInfo1 = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; - Ofs1 = fInfo1->Offset; - if (n == recN->vmtInfo->fields->Count - 1) { - Ofs2 = 0x7FFFFFFF; - } - else { - fInfo2 = (PFIELDINFO)recN->vmtInfo->fields->Items[n + 1]; - Ofs2 = fInfo2->Offset; - } - if (Offset >= Ofs1 && Offset < Ofs2) { - if (Offset == Ofs1) - return fInfo1; - kind = GetTypeKind(fInfo1->Type, &size); - if (kind == ikClass || kind == ikRecord) { - prefix = fInfo1->Name; - fInfo = GetField(fInfo1->Type, Offset - Ofs1, vmt, vmtAdr, prefix); - if (fInfo) { - fInfo->Offset = Offset; - fInfo->Name = prefix + "." + fInfo->Name; - return fInfo; - } - return 0; - } - if (kind == ikArray) - return fInfo1; - return 0; - } - } - } - } - return 0; - } - - // try KB - uses = KnowledgeBase.GetTypeUses(AnsiString(TypeName).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(TypeName).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS, tInfo)) - if (tInfo->Fields) { - p = tInfo->Fields; - for (n = 0; n < tInfo->FieldsNum; n++) { - ps = p; - p++; // scope - Ofs1 = *((int*)p); - p += 4; // offset - p += 4; // case - Len = *((WORD*)p); - p += Len + 3; // name - Len = *((WORD*)p); - p += Len + 3; // type - if (n == tInfo->FieldsNum - 1) { - Ofs2 = 0x7FFFFFFF; - } - else { - Ofs2 = *((int*)(p + 1)); - } - if (Offset >= Ofs1 && Offset < Ofs2) { - p = ps; - p++; // Scope - Ofs = *((int*)p); - p += 4; // offset - fInfo = new FIELDINFO; - fInfo->Offset = Offset - Ofs; - fInfo->Scope = SCOPE_TMP; - fInfo->Case = *((int*)p); - p += 4; - fInfo->xrefs = 0; - Len = *((WORD*)p); - p += 2; - fInfo->Name = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - fInfo->Type = TrimTypeName(String((char*)p, Len)); - return fInfo; - } - } - return 0; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -PFIELDINFO __fastcall TFMain_11011981::AddField(DWORD ProcAdr, int ProcOfs, String TypeName, BYTE Scope, int Offset, int Case, String Name, String Type) { - DWORD classAdr = GetClassAdr(TypeName); - if (IsValidImageAdr(classAdr)) { - if (Offset < 4) - return 0; - - DWORD prevClassAdr = 0; - while (classAdr && Offset < GetClassSize(classAdr)) { - prevClassAdr = classAdr; - classAdr = GetParentAdr(classAdr); - } - classAdr = prevClassAdr; - - if (classAdr) { - PInfoRec recN = GetInfoRec(classAdr); - if (!recN) - return 0; - if (!recN->vmtInfo) - return 0; - return recN->vmtInfo->AddField(ProcAdr, ProcOfs, Scope, Offset, Case, Name, Type); - } - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miUnitDumperClick(TObject *Sender) {; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miFuzzyScanKBClick(TObject *Sender) { - FKBViewer_11011981->Position = -1; - if (CurProcAdr) { - PInfoRec recN = GetInfoRec(CurProcAdr); - if (recN && recN->kbIdx != -1) { - FKBViewer_11011981->Position = recN->kbIdx; - FKBViewer_11011981->ShowCode(CurProcAdr, recN->kbIdx); - FKBViewer_11011981->Show(); - return; - } - - PUnitRec recU = GetUnit(CurProcAdr); - if (recU) { - int fromAdr = recU->fromAdr, toAdr = recU->toAdr; - int upIdx = -1, dnIdx = -1, upCnt = -1, dnCnt = -1; - if (1) // !recU->names->Count) - { - if (FKBViewer_11011981->cbUnits->Text != "") { - FKBViewer_11011981->cbUnitsChange(this); - } - else if (recU->names->Count) { - FKBViewer_11011981->cbUnits->Text = recU->names->Strings[0]; - FKBViewer_11011981->cbUnitsChange(this); - } - if (FKBViewer_11011981->Position != -1) { - FKBViewer_11011981->Show(); - } - else { - for (int adr = CurProcAdr; adr >= fromAdr; adr--) { - if (IsFlagSet(cfProcStart, Adr2Pos(adr))) { - upCnt++; - recN = GetInfoRec(adr); - if (recN && recN->kbIdx != -1) { - upIdx = recN->kbIdx; - break; - } - } - } - for (int adr = CurProcAdr; adr < toAdr; adr++) { - if (IsFlagSet(cfProcStart, Adr2Pos(adr))) { - dnCnt++; - recN = GetInfoRec(adr); - if (recN && recN->kbIdx != -1) { - dnIdx = recN->kbIdx; - break; - } - } - } - if (upIdx != -1) { - if (dnIdx != -1) { - // Up proc is nearest - if (upCnt < dnCnt) { - FKBViewer_11011981->Position = upIdx + upCnt; - FKBViewer_11011981->ShowCode(CurProcAdr, upIdx + upCnt); - FKBViewer_11011981->Show(); - } - // Down is nearest - else { - FKBViewer_11011981->Position = dnIdx - dnCnt; - FKBViewer_11011981->ShowCode(CurProcAdr, dnIdx - dnCnt); - FKBViewer_11011981->Show(); - } - } - else { - FKBViewer_11011981->Position = upIdx + upCnt; - FKBViewer_11011981->ShowCode(CurProcAdr, upIdx + upCnt); - FKBViewer_11011981->Show(); - } - } - else if (dnIdx != -1) { - FKBViewer_11011981->Position = dnIdx - dnCnt; - FKBViewer_11011981->ShowCode(CurProcAdr, dnIdx - dnCnt); - FKBViewer_11011981->Show(); - } - // Nothing found! - else { - FKBViewer_11011981->Position = -1; - FKBViewer_11011981->ShowCode(CurProcAdr, -1); - FKBViewer_11011981->Show(); - } - } - return; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::InitAliases(bool find) { - TCursor curCursor = Screen->Cursor; - Screen->Cursor = crHourGlass; - - if (find) - ResInfo->InitAliases(); - - lClassName->Caption = ""; - lbAliases->Clear(); - - for (int n = 0; n < ResInfo->Aliases->Count; n++) { - String item = ResInfo->Aliases->Strings[n]; - if (item.Pos("=")) { - - char *p = AnsiString(AnsiLastChar(item)).c_str(); - if (p && *p != '=') - lbAliases->Items->Add(item); - } - } - - cbAliases->Clear(); - - for (int n = 0; ; n++) { - if (!RegClasses[n].RegClass) - break; - - if (RegClasses[n].ClassName) - cbAliases->Items->Add(String(RegClasses[n].ClassName)); - } - - pnlAliases->Visible = false; - lbAliases->Enabled = true; - Screen->Cursor = curCursor; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbAliasesDblClick(TObject *Sender) { - lClassName->Caption = ""; - cbAliases->Text = ""; - String item = lbAliases->Items->Strings[lbAliases->ItemIndex]; - int pos = item.Pos("="); - if (pos) { - pnlAliases->Visible = true; - lClassName->Caption = item.SubString(1, pos - 1); - cbAliases->Text = item.SubString(pos + 1, item.Length() - pos); - lbAliases->Enabled = false; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::bApplyAliasClick(TObject *Sender) { - ResInfo->Aliases->Values[lClassName->Caption] = cbAliases->Text; - pnlAliases->Visible = false; - lbAliases->Items->Strings[lbAliases->ItemIndex] = lClassName->Caption + "=" + cbAliases->Text; - lbAliases->Enabled = true; - - // as: we any opened Forms -> repaint (take into account new aliases) - ResInfo->ReopenAllForms(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::bCancelAliasClick(TObject *Sender) { - pnlAliases->Visible = false; - lbAliases->Enabled = true; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miLegendClick(TObject *Sender) { - FLegend_11011981->ShowModal(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCopyListClick(TObject *Sender) { - int n, m, k, u, dot, idx, usesNum; - PInfoRec recN; - PUnitRec recU; - MProcInfo aInfo; - MProcInfo *pInfo = &aInfo; - FILE *outFile; - TStringList *tmpList; - String moduleName, importName; - WORD uses[128]; - - SaveDlg->InitialDir = WrkDir; - SaveDlg->FileName = "units.lst"; - - if (SaveDlg->Execute()) { - if (FileExists(SaveDlg->FileName)) { - if (Application->MessageBox(L"File already exists. Overwrite?", L"Warning", MB_YESNO) == IDNO) - return; - } - - outFile = fopen(AnsiString(SaveDlg->FileName).c_str(), "wt+"); - if (!outFile) { - ShowMessage("Cannot save units list"); - return; - } - Screen->Cursor = crHourGlass; - tmpList = new TStringList; - for (n = 0; n < UnitsNum; n++) { - recU = (UnitRec*)Units->Items[n]; - for (u = 0; u < recU->names->Count; u++) { - if (tmpList->IndexOf(recU->names->Strings[u]) == -1) - tmpList->Add(recU->names->Strings[u]); - } - // Add Imports - for (m = 0; m < CodeSize; m += 4) { - if (IsFlagSet(cfImport, m)) { - recN = GetInfoRec(Pos2Adr(m)); - dot = recN->GetName().Pos("."); - importName = recN->GetName().SubString(dot + 1, recN->GetNameLength()); - usesNum = KnowledgeBase.GetProcUses(AnsiString(importName).c_str(), uses); - for (k = 0; k < usesNum; k++) { - idx = KnowledgeBase.GetProcIdx(uses[k], AnsiString(importName).c_str()); - if (idx != -1) { - idx = KnowledgeBase.ProcOffsets[idx].NamId; - if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) { - moduleName = KnowledgeBase.GetModuleName(pInfo->ModuleID); - if (tmpList->IndexOf(moduleName) == -1) - tmpList->Add(moduleName); - } - } - } - } - } - tmpList->Sort(); - } - // Output result - for (n = 0; n < tmpList->Count; n++) { - fprintf(outFile, "%s.dcu\n", tmpList->Strings[n].c_str()); - } - delete tmpList; - fclose(outFile); - Screen->Cursor = crDefault; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::wm_updAnalysisStatus(TMessage& msg) { - if (taUpdateUnits == msg.WParam) { - const long isLastStep = msg.LParam; - tsUnits->Enabled = true; - ShowUnits(isLastStep); - ShowUnitItems(GetUnit(CurUnitAdr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - } - else if (taUpdateRTTIs == msg.WParam) { - miSearchRTTI->Enabled = true; - miSortRTTI->Enabled = true; - tsRTTIs->Enabled = true; - ShowRTTIs(); - } - else if (taUpdateVmtList == msg.WParam) { - FillVmtList(); - InitAliases(true); - } - else if (taUpdateStrings == msg.WParam) { - tsStrings->Enabled = true; - miSearchString->Enabled = true; - ShowStrings(0); - tsNames->Enabled = true; - ShowNames(0); - } - else if (taUpdateCode == msg.WParam) { - tsCodeView->Enabled = true; - bEP->Enabled = true; - DWORD adr = CurProcAdr; - CurProcAdr = 0; - ShowCode(adr, lbCode->ItemIndex, -1, lbCode->TopIndex); - } - else if (taUpdateXrefs == msg.WParam) { - lbCXrefs->Enabled = true; - miGoTo->Enabled = true; - miExploreAdr->Enabled = true; - miSwitchFlag->Enabled = cbMultipleSelection->Checked; - } - else if (taUpdateShortClassViewer == msg.WParam) { - tsClassView->Enabled = true; - miViewClass->Enabled = true; - miSearchVMT->Enabled = true; - miCollapseAll->Enabled = true; - - rgViewerMode->ItemIndex = 1; - rgViewerMode->Enabled = false; - } - else if (taUpdateClassViewer == msg.WParam) { - tsClassView->Enabled = true; - miSearchVMT->Enabled = true; - miCollapseAll->Enabled = true; - - if (ClassTreeDone) { - TTreeNode *root = tvClassesFull->Items->Item[0]; - root->Expanded = true; - miViewClass->Enabled = true; - rgViewerMode->ItemIndex = 0; - rgViewerMode->Enabled = true; - } - else { - miViewClass->Enabled = true; - rgViewerMode->ItemIndex = 1; - rgViewerMode->Enabled = false; - } - miClassTreeBuilder->Enabled = true; - } - else if (taUpdateBeforeClassViewer == msg.WParam) { - miSearchUnit->Enabled = true; - miRenameUnit->Enabled = true; - miSortUnits->Enabled = true; - miCopyList->Enabled = true; - miKBTypeInfo->Enabled = true; - miCtdPassword->Enabled = IsValidCodeAdr(CtdRegAdr); - miName->Enabled = true; - miViewProto->Enabled = true; - miEditFunctionC->Enabled = true; - miEditFunctionI->Enabled = true; - miEditClass->Enabled = true; - } - else if (taFinished == msg.WParam) { - AnalyzeThreadDone(0); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::wm_dfmClosed(TMessage& msg) { -} - -// --------------------------------------------------------------------------- -// Fill ClassViewerTree for 1 class -void __fastcall TFMain_11011981::FillClassViewerOne(int n, TStringList* tmpList, const bool* terminated) { - bool vmtProc; - WORD _dx, _bx, _si; - int m, size, sizeParent, pos, cnt, vmtOfs, _pos; - DWORD vmtAdr, vmtAdrParent, vAdr, iAdr; - TTreeNode *rootNode, *node; - String className, nodeTextParent, nodeText, line, name; - PInfoRec recN; - PMethodRec recM; - PVmtListRec recV; - DISINFO disInfo; - - recV = (PVmtListRec)VmtList->Items[n]; - vmtAdr = recV->vmtAdr; - - className = GetClsName(vmtAdr); - - size = GetClassSize(vmtAdr); - if (DelphiVersion >= 2009) - size += 4; - - vmtAdrParent = GetParentAdr(vmtAdr); - sizeParent = GetClassSize(vmtAdrParent); - if (DelphiVersion >= 2009) - sizeParent += 4; - - nodeTextParent = GetParentName(vmtAdr) + " #" + Val2Str8(vmtAdrParent) + " Sz=" + Val2Str1(sizeParent); - nodeText = className + " #" + Val2Str8(vmtAdr) + " Sz=" + Val2Str1(size); - node = FindTreeNodeByName(nodeTextParent); - node = AddClassTreeNode(node, nodeText); - - rootNode = node; - - if (rootNode) { - // Interfaces - const int intfsNum = LoadIntfTable(vmtAdr, tmpList); - if (intfsNum) { - for (m = 0; m < intfsNum && !*terminated; m++) { - nodeText = tmpList->Strings[m]; - sscanf(AnsiString(nodeText).c_str(), "%lX", &vAdr); - if (IsValidCodeAdr(vAdr)) { - TTreeNode *intfsNode = AddClassTreeNode(rootNode, " " + nodeText.SubString(nodeText.Pos(' ') + 1, nodeText.Length())); - cnt = 0; - pos = Adr2Pos(vAdr); - for (int v = 0; ; v += 4) { - if (IsFlagSet(cfVTable, pos)) - cnt++; - if (cnt == 2) - break; - iAdr = *((DWORD*)(Code + pos)); - DWORD _adr = iAdr; - _pos = Adr2Pos(_adr); - vmtProc = false; - vmtOfs = 0; - _dx = 0; - _bx = 0; - _si = 0; - while (1) { - int instrlen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &disInfo, 0); - if ((disInfo.OpType[0] == otMEM || disInfo.OpType[1] == otMEM) && disInfo.BaseReg != 20) - // to exclude instruction "xchg reg, [esp]" - { - vmtOfs = disInfo.Offset; - } - if (disInfo.OpType[0] == otREG && disInfo.OpType[1] == otIMM) { - if (disInfo.OpRegIdx[0] == 10) // dx - _dx = disInfo.Immediate; - else if (disInfo.OpRegIdx[0] == 11) // bx - _bx = disInfo.Immediate; - else if (disInfo.OpRegIdx[0] == 14) // si - _si = disInfo.Immediate; - } - if (disInfo.Call) { - recN = GetInfoRec(disInfo.Immediate); - if (recN) { - if (recN->SameName("@CallDynaInst") || recN->SameName("@CallDynaClass")) { - if (DelphiVersion <= 5) - GetDynaInfo(vmtAdr, _bx, &iAdr); - else - GetDynaInfo(vmtAdr, _si, &iAdr); - break; - } - else if (recN->SameName("@FindDynaInst") || recN->SameName("@FindDynaClass")) { - GetDynaInfo(vmtAdr, _dx, &iAdr); - break; - } - } - } - if (disInfo.Branch && !disInfo.Conditional) { - if (IsValidImageAdr(disInfo.Immediate)) { - iAdr = disInfo.Immediate; - } - else { - vmtProc = true; - iAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr - VmtSelfPtr + vmtOfs))); - recM = GetMethodInfo(vmtAdr, 'V', vmtOfs); - if (recM) - name = recM->name; - } - break; - } - else if (disInfo.Ret) { - vmtProc = true; - iAdr = *((DWORD*)(Code + Adr2Pos(vmtAdr - VmtSelfPtr + vmtOfs))); - recM = GetMethodInfo(vmtAdr, 'V', vmtOfs); - if (recM) - name = recM->name; - break; - } - _pos += instrlen; - _adr += instrlen; - } - if (!vmtProc && IsValidImageAdr(iAdr)) { - recN = GetInfoRec(iAdr); - if (recN && recN->HasName()) - name = recN->GetName(); - else - name = ""; - } - line = "I" + Val2Str4(v) + " #" + Val2Str8(iAdr); - if (name != "") - line += " " + name; - AddClassTreeNode(intfsNode, line); - pos += 4; - } - } - else { - TTreeNode *intfsNode = AddClassTreeNode(rootNode, " " + nodeText); - } - } - } - if (*terminated) - return; - // Automated - const int autoNum = LoadAutoTable(vmtAdr, tmpList); - if (autoNum) { - nodeText = ""; - TTreeNode* autoNode = AddClassTreeNode(rootNode, nodeText); - for (m = 0; m < autoNum && !*terminated; m++) { - nodeText = tmpList->Strings[m]; - AddClassTreeNode(autoNode, nodeText); - } - } - /* - //Fields - const int fieldsNum = form->LoadFieldTable(vmtAdr, fieldsList); - if (fieldsNum) - { - node = rootNode; - nodeText = ""; - //node = form->tvClassesFull->Items->AddChild(node, nodeText); - node = AddClassTreeNode(node, nodeText); - TTreeNode* fieldsNode = node; - for (m = 0; m < fieldsNum && !Terminated; m++) - { - //node = fieldsNode; - PFIELDINFO fInfo = (PFIELDINFO)fieldsList->Items[m]; - nodeText = Val2Str5(fInfo->Offset) + " "; - if (fInfo->Name != "") - nodeText += fInfo->Name; - else - nodeText += "?"; - nodeText += ":"; - if (fInfo->Type != "") - nodeText += fInfo->Type; - else - nodeText += "?"; - - //node = form->tvClassesFull->Items->AddChild(node, nodeText); - AddClassTreeNode(fieldsNode, nodeText); - } - } - */ - if (*terminated) - return; - // Events - const int methodsNum = LoadMethodTable(vmtAdr, tmpList); - if (methodsNum) { - nodeText = ""; - TTreeNode* methodsNode = AddClassTreeNode(rootNode, nodeText); - for (m = 0; m < methodsNum && !*terminated; m++) { - nodeText = tmpList->Strings[m]; - AddClassTreeNode(methodsNode, nodeText); - } - } - if (*terminated) - return; - // Dynamics - const int dynamicsNum = LoadDynamicTable(vmtAdr, tmpList); - if (dynamicsNum) { - nodeText = ""; - TTreeNode* dynamicsNode = AddClassTreeNode(rootNode, nodeText); - for (m = 0; m < dynamicsNum && !*terminated; m++) { - nodeText = tmpList->Strings[m]; - AddClassTreeNode(dynamicsNode, nodeText); - } - } - if (*terminated) - return; - // Virtual - const int virtualsNum = LoadVirtualTable(vmtAdr, tmpList); - if (virtualsNum) { - nodeText = ""; - TTreeNode* virtualsNode = AddClassTreeNode(rootNode, nodeText); - for (m = 0; m < virtualsNum && !*terminated; m++) { - nodeText = tmpList->Strings[m]; - AddClassTreeNode(virtualsNode, nodeText); - } - } - } -} - -// --------------------------------------------------------------------------- -TTreeNode* __fastcall TFMain_11011981::AddClassTreeNode(TTreeNode* node, String nodeText) { - TTreeNode* newNode = 0; - if (!node) // Root - newNode = tvClassesFull->Items->Add(0, nodeText); - else - newNode = tvClassesFull->Items->AddChild(node, nodeText); - - AddTreeNodeWithName(newNode, nodeText); - - return newNode; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSaveDelphiProjectClick(TObject *Sender) { - bool typePresent, _isForm, comment; - BYTE kind; - int n, m, k, num, dotpos, len, minValue, maxValue; - DWORD adr, adr1, parentAdr; - FILE *f; - TList *tmpList; - TStringList *intBodyLines; - TStringList *intUsesLines; - // TStringList *impBodyLines; - // TStringList *impUsesLines; - TStringList *unitsList; - TStringList *formList; - TStringList *publishedList; - TStringList *publicList; - TSearchRec sr; - PUnitRec recU; - PInfoRec recN; - PFIELDINFO fInfo; - PMethodRec recM; - PVmtListRec recV; - TDfm *dfm; - PComponentInfo cInfo; - String curDir, DelphiProjectPath; - String unitName, className, parentName, fieldName, typeName; - String procName, formName, dfmName, line, uName; - - curDir = GetCurrentDir(); - DelphiProjectPath = AppDir + "Projects"; - if (DirectoryExists(DelphiProjectPath)) { - ChDir(DelphiProjectPath); - if (!FindFirst("*.*", faArchive, sr)) { - do { - DeleteFile(sr.Name); - } - while (!FindNext(sr)); - - FindClose(sr); - } - } - else { - if (!CreateDir(DelphiProjectPath)) - return; - ChDir(DelphiProjectPath); - } - Screen->Cursor = crHourGlass; - // Save Forms - for (n = 0; n < ResInfo->FormList->Count; n++) { - dfm = (TDfm*)ResInfo->FormList->Items[n]; - formList = new TStringList; - ResInfo->GetFormAsText(dfm, formList); - dfmName = dfm->Name; - // If system name add F at start - if (SameText(dfmName, "prn")) - dfmName = "F" + dfmName; - formList->SaveToFile(dfmName + ".dfm"); - delete formList; - } - - unitsList = new TStringList; - - for (n = 0; n < UnitsNum; n++) { - recU = (PUnitRec)Units->Items[n]; - if (recU->trivial) - continue; - typePresent = false; - _isForm = false; - unitName = GetUnitName(recU); - tmpList = new TList; - intBodyLines = new TStringList; - intUsesLines = new TStringList; - // impBodyLines = new TStringList; - // impUsesLines = new TStringList; - publishedList = new TStringList; - publicList = new TStringList; - - intUsesLines->Add("SysUtils"); - intUsesLines->Add("Classes"); - for (adr = recU->fromAdr; adr < recU->toAdr; adr++) { - recN = GetInfoRec(adr); - if (!recN) - continue; - - kind = recN->kind; - switch (kind) { - case ikEnumeration: - case ikSet: - case ikMethod: - case ikArray: - case ikRecord: - case ikDynArray: - typePresent = true; - line = FTypeInfo_11011981->GetRTTI(adr); - len = sprintf(StringBuf, " %s = %s;", recN->GetName().c_str(), line.c_str()); - intBodyLines->Add(String(StringBuf, len)); - break; - // class - case ikVMT: - typePresent = true; - className = recN->GetName(); - publishedList->Clear(); - publicList->Clear(); - - dfm = ResInfo->GetFormByClassName(className); - if (dfm) { - _isForm = true; - len = sprintf(StringBuf, "%s in '%s.pas' {%s}", unitName, unitName, dfm->Name); - unitsList->Add(String(StringBuf, len)); - } - - parentAdr = GetParentAdr(adr); - parentName = GetClsName(parentAdr); - len = sprintf(StringBuf, " %s = class(%s)", className.c_str(), parentName.c_str()); - intBodyLines->Add(String(StringBuf, len)); - - num = LoadFieldTable(adr, tmpList); - for (m = 0; m < num; m++) { - fInfo = (PFIELDINFO)tmpList->Items[m]; - if (fInfo->Name != "") - fieldName = fInfo->Name; - else - fieldName = "f" + Val2Str0(fInfo->Offset); - if (fInfo->Type != "") { - comment = false; - typeName = TrimTypeName(fInfo->Type); - } - else { - comment = true; - typeName = "?"; - } - // Add UnitName to UsesList if necessary - for (k = 0; k < VmtList->Count; k++) { - recV = (PVmtListRec)VmtList->Items[k]; - if (recV && SameText(typeName, recV->vmtName)) { - uName = GetUnitName(recV->vmtAdr); - if (intUsesLines->IndexOf(uName) == -1) - intUsesLines->Add(uName); - break; - } - } - - if (!comment) - len = sprintf(StringBuf, " %s:%s;//f%X", fieldName.c_str(), typeName.c_str(), fInfo->Offset); - else - len = sprintf(StringBuf, " //%s:%s;//f%X", fieldName.c_str(), typeName.c_str(), fInfo->Offset); - if (_isForm && dfm && dfm->IsFormComponent(fieldName)) - publishedList->Add(String(StringBuf, len)); - else - publicList->Add(String(StringBuf, len)); - - } - - num = LoadMethodTable(adr, tmpList); - for (m = 0; m < num; m++) { - recM = (PMethodRec)tmpList->Items[m]; - recN = GetInfoRec(recM->address); - procName = recN->MakePrototype(recM->address, true, false, false, false, false); - if (!procName.Pos(":?")) - len = sprintf(StringBuf, " %s", procName); - else - len = sprintf(StringBuf, " //%s", procName); - publishedList->Add(String(StringBuf, len)); - } - - num = LoadVirtualTable(adr, tmpList); - for (m = 0; m < num; m++) { - recM = (PMethodRec)tmpList->Items[m]; - // Check if procadr from other class - if (!IsOwnVirtualMethod(adr, recM->address)) - continue; - - recN = GetInfoRec(recM->address); - procName = recN->MakeDelphiPrototype(recM->address, recM); - - len = sprintf(StringBuf, " "); - if (procName.Pos(":?")) - len += sprintf(StringBuf + len, "//"); - len += sprintf(StringBuf + len, "%s", procName.c_str()); - if (recM->id >= 0) - len += sprintf(StringBuf + len, "//v%X", recM->id); - len += sprintf(StringBuf + len, "//%08lX", recM->address); - - publicList->Add(String(StringBuf, len)); - } - - num = LoadDynamicTable(adr, tmpList); - for (m = 0; m < num; m++) { - recM = (PMethodRec)tmpList->Items[m]; - recN = GetInfoRec(recM->address); - procName = recN->MakePrototype(recM->address, true, false, false, false, false); - PMsgMInfo _info = GetMsgInfo(recM->id); - if (_info && _info->msgname != "") { - procName += String(" message ") + _info->msgname + ";"; - } - else - procName += " dynamic;"; - - if (!procName.Pos(":?")) - len = sprintf(StringBuf, " %s", procName.c_str()); - else - len = sprintf(StringBuf, " //%s", procName.c_str()); - publicList->Add(String(StringBuf, len)); - } - - if (publishedList->Count) { - intBodyLines->Add(" published"); - for (m = 0; m < publishedList->Count; m++) { - intBodyLines->Add(publishedList->Strings[m]); - } - } - if (publicList->Count) { - intBodyLines->Add(" public"); - for (m = 0; m < publicList->Count; m++) { - intBodyLines->Add(publicList->Strings[m]); - } - } - - for (adr1 = recU->fromAdr; adr1 < recU->toAdr; adr1++) { - // Skip Initialization and Finalization procs - if (adr1 == recU->iniadr || adr1 == recU->finadr) - continue; - recN = GetInfoRec(adr1); - if (!recN || !recN->procInfo) - continue; - dotpos = recN->GetName().Pos("."); - if (!dotpos || !SameText(className, recN->GetName().SubString(1, dotpos - 1))) - continue; - if ((recN->procInfo->flags & PF_VIRTUAL) || (recN->procInfo->flags & PF_DYNAMIC) || (recN->procInfo->flags & PF_EVENT)) - continue; - - if (recN->kind == ikConstructor || (recN->procInfo->flags & PF_METHOD)) { - procName = recN->MakePrototype(adr1, true, false, false, false, false); - if (!procName.Pos(":?")) - len = sprintf(StringBuf, " %s", procName.c_str()); - else - len = sprintf(StringBuf, " //%s", procName.c_str()); - if (intBodyLines->IndexOf(String(StringBuf, len)) == -1) - intBodyLines->Add(String(StringBuf, len)); - } - } - intBodyLines->Add(" end;"); - break; - } - } - // Output information - f = fopen(AnsiString(unitName + ".pas").c_str(), "wt+"); - OutputDecompilerHeader(f); - fprintf(f, "unit %s;\n\n", unitName); - fprintf(f, "interface\n"); - // Uses - if (intUsesLines->Count) { - fprintf(f, "\nuses\n "); - for (m = 0; m < intUsesLines->Count; m++) { - if (m) - fprintf(f, ", "); - fprintf(f, "%s", intUsesLines->Strings[m].c_str()); - } - fprintf(f, ";\n\n"); - } - // Type - if (typePresent) - fprintf(f, "type\n"); - for (m = 0; m < intBodyLines->Count; m++) { - fprintf(f, "%s\n", intBodyLines->Strings[m].c_str()); - } - // Other procs (not class members) - for (adr = recU->fromAdr; adr < recU->toAdr; adr++) { - // Skip Initialization and Finalization procs - if (adr == recU->iniadr || adr == recU->finadr) - continue; - - recN = GetInfoRec(adr); - if (!recN || !recN->procInfo) - continue; - - procName = recN->MakePrototype(adr, true, false, false, false, false); - if (!procName.Pos(":?")) - len = sprintf(StringBuf, " %s", procName.c_str()); - else - len = sprintf(StringBuf, " //%s", procName.c_str()); - - if (intBodyLines->IndexOf(String(StringBuf, len)) != -1) - continue; - - fprintf(f, "%s\n", StringBuf); - } - - fprintf(f, "\nimplementation\n\n"); - if (_isForm) - fprintf(f, "{$R *.DFM}\n\n"); - for (adr = recU->fromAdr; adr < recU->toAdr; adr++) { - // Initialization and Finalization procs - if (adr == recU->iniadr || adr == recU->finadr) - continue; - - recN = GetInfoRec(adr); - if (!recN || !recN->procInfo) - continue; - - kind = recN->kind; - if (kind == ikConstructor || kind == ikDestructor || kind == ikProc || kind == ikFunc) { - fprintf(f, "//%08lX\n", adr); - procName = recN->MakePrototype(adr, true, false, false, true, false); - if (!procName.Pos(":?")) { - fprintf(f, "%s\n", procName); - fprintf(f, "begin\n"); - fprintf(f, "{*\n"); - OutputCode(f, adr, "", false); - fprintf(f, "*}\n"); - fprintf(f, "end;\n\n"); - } - else { - fprintf(f, "{*%s\n", procName); - fprintf(f, "begin\n"); - OutputCode(f, adr, "", false); - fprintf(f, "end;*}\n\n"); - } - } - } - - if (!recU->trivialIni || !recU->trivialFin) { - fprintf(f, "Initialization\n"); - if (!recU->trivialIni) { - fprintf(f, "//%08lX\n", recU->iniadr); - fprintf(f, "{*\n"); - OutputCode(f, recU->iniadr, "", false); - fprintf(f, "*}\n"); - } - fprintf(f, "Finalization\n"); - if (!recU->trivialFin) { - fprintf(f, "//%08lX\n", recU->finadr); - fprintf(f, "{*\n"); - OutputCode(f, recU->finadr, "", false); - fprintf(f, "*}\n"); - } - } - - fprintf(f, "end."); - fclose(f); - - delete tmpList; - delete intBodyLines; - delete intUsesLines; - // delete impBodyLines; - // delete impUsesLines; - delete publishedList; - delete publicList; - } - // dpr - recU = (PUnitRec)Units->Items[UnitsNum - 1]; - unitName = recU->names->Strings[0]; - f = fopen(AnsiString(unitName + ".dpr").c_str(), "wt+"); - - OutputDecompilerHeader(f); - - if (SourceIsLibrary) - fprintf(f, "library %s;\n\n", unitName); - else - fprintf(f, "program %s;\n\n", unitName); - - fprintf(f, "uses\n"); - fprintf(f, " SysUtils, Classes;\n\n"); - - fprintf(f, "{$R *.res}\n\n"); - - if (SourceIsLibrary) { - bool _expExists = false; - for (n = 0; n < ExpFuncList->Count; n++) { - PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[n]; - adr = recE->address; - if (IsValidImageAdr(adr)) { - fprintf(f, "//%08lX\n", adr); - recN = GetInfoRec(adr); - if (recN) { - fprintf(f, "%s\n", recN->MakePrototype(adr, true, false, false, true, false)); - fprintf(f, "begin\n"); - fprintf(f, "{*\n"); - OutputCode(f, adr, "", false); - fprintf(f, "*}\n"); - fprintf(f, "end;\n\n"); - _expExists = true; - } - else { - fprintf(f, "//No information\n\n"); - } - } - } - if (_expExists) { - fprintf(f, "exports\n"); - for (n = 0; n < ExpFuncList->Count; n++) { - PExportNameRec recE = (PExportNameRec)ExpFuncList->Items[n]; - adr = recE->address; - if (IsValidImageAdr(adr)) { - recN = GetInfoRec(adr); - if (recN) { - fprintf(f, "%s", recN->GetName()); - if (n < ExpFuncList->Count - 1) - fprintf(f, ",\n"); - } - } - } - fprintf(f, ";\n\n"); - } - } - - fprintf(f, "//%08lX\n", EP); - fprintf(f, "begin\n"); - fprintf(f, "{*\n"); - OutputCode(f, EP, "", false); - fprintf(f, "*}\n"); - fprintf(f, "end.\n"); - fclose(f); - - delete unitsList; - - ChDir(curDir); - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::bDecompileClick(TObject *Sender) { - int procSize = GetProcSize(CurProcAdr); - if (procSize > 0) { - TDecompileEnv *DeEnv = new TDecompileEnv(CurProcAdr, procSize, GetInfoRec(CurProcAdr)); - try { - DeEnv->DecompileProc(); - } - catch (Exception &exception) { - ShowCode(DeEnv->StartAdr, DeEnv->ErrAdr, lbCXrefs->ItemIndex, -1); - Application->ShowException(&exception); - } - DeEnv->OutputSourceCode(); - if (DeEnv->Alarm) - tsSourceCode->Highlighted = true; - else - tsSourceCode->Highlighted = false; - if (!DeEnv->ErrAdr) - pcWorkArea->ActivePage = tsSourceCode; - delete DeEnv; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miHex2DoubleClick(TObject *Sender) { - FHex2DoubleDlg_11011981->ShowModal(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::acFontAllExecute(TObject *Sender) { - FontsDlg->Font->Assign(lbCode->Font); - if (FontsDlg->Execute()) - SetupAllFonts(FontsDlg->Font); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::SetupAllFonts(TFont* font) { - TListBox* formListBoxes[] = {lbUnits, lbRTTIs, lbForms, lbAliases, lbCode, lbStrings, lbNames, lbNXrefs, lbSXrefs, lbCXrefs, lbSourceCode, lbUnitItems, 0}; - - TTreeView* formTreeViews[] = {tvClassesShort, tvClassesFull, 0}; - - for (int n = 0; formListBoxes[n]; n++) { - formListBoxes[n]->Font->Assign(font); - } - - for (int n = 0; formTreeViews[n]; n++) { - formTreeViews[n]->Font->Assign(font); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmUnitItemsPopup(TObject *Sender) { - miEditFunctionI->Enabled = (lbUnitItems->ItemIndex >= 0); - miCopyAddressI->Enabled = (lbUnitItems->ItemIndex >= 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::CopyAddress(String line, int ofs, int bytes) { - char buf[9], *p = buf; - - Clipboard()->Open(); - for (int n = 1; n <= bytes; n++) { - *p = line[n + ofs]; - p++; - } - *p = 0; - Clipboard()->SetTextBuf(String(buf).c_str()); - Clipboard()->Close(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCopyAddressCodeClick(TObject *Sender) { - int bytes = (lbCode->ItemIndex) ? 8 : 0; - CopyAddress(lbCode->Items->Strings[lbCode->ItemIndex], 1, bytes); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ClearPassFlags() { - ClearFlags(cfPass0 | cfPass1 | cfPass2 | cfPass, 0, TotalSize); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCopySource2ClipboardClick(TObject *Sender) { - Copy2Clipboard(lbSourceCode->Items, 0, false); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmCodePopup(TObject *Sender) { - int _ap; - DWORD _adr; - DISINFO _disInfo; - - miXRefs->Enabled = false; - miXRefs->Clear(); - - if (ActiveControl == lbCode) { - if (lbCode->ItemIndex <= 0) - return; - DWORD adr; - sscanf(AnsiString(lbCode->Items->Strings[lbCode->ItemIndex]).c_str() + 2, "%lX", &adr); - if (adr != CurProcAdr && IsFlagSet(cfLoc, Adr2Pos(adr))) { - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->xrefs && recN->xrefs->Count > 0) { - miXRefs->Enabled = true; - miXRefs->Clear(); - for (int n = 0; n < recN->xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; - _adr = recX->adr + recX->offset; - _ap = Adr2Pos(_adr); - Disasm.Disassemble(Code + _ap, (__int64)_adr, &_disInfo, 0); - TMenuItem* mi = new TMenuItem(pmCode); - mi->Caption = Val2Str8(_adr) + " " + _disInfo.Mnem; - mi->Tag = _adr; - mi->OnClick = GoToXRef; - miXRefs->Add(mi); - } - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::GoToXRef(TObject *Sender) { - TMenuItem* mi = (TMenuItem*)Sender; - DWORD Adr = mi->Tag; - if (Adr && IsValidCodeAdr(Adr)) { - PROCHISTORYREC rec; - - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(CurProcAdr, Adr, lbCXrefs->ItemIndex, -1); - CodeHistoryPush(&rec); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbFormsClick(TObject *Sender) { - FormsSearchFrom = lbForms->ItemIndex; - WhereSearch = SEARCH_FORMS; -} -// --------------------------------------------------------------------------- - -void __fastcall TFMain_11011981::lbCodeClick(TObject *Sender) { - WhereSearch = SEARCH_CODEVIEWER; - - if (lbCode->ItemIndex <= 0) - return; - - String prevItem = SelectedAsmItem; - SelectedAsmItem = ""; - String text = lbCode->Items->Strings[lbCode->ItemIndex]; - int textLen = text.Length(); - - TPoint cursorPos; - GetCursorPos(&cursorPos); - cursorPos = lbCode->ScreenToClient(cursorPos); - for (int n = 1, wid = 0; n <= textLen; n++) { - int cwid = lbCode->Canvas->TextWidth(text[n]); - if (wid > cursorPos.x) { - char c; - int beg = n - 1; - while (beg >= 1) { - c = text[beg]; - if (!isalpha(c) && !isdigit(c) && c != '@') { - beg++; - break; - } - beg--; - } - int end = beg; - while (end <= textLen) { - c = text[end]; - if (!isalpha(c) && !isdigit(c) && c != '@') { - end--; - break; - } - end++; - } - SelectedAsmItem = text.SubString(beg, end - beg + 1); - break; - } - wid += cwid; - } - if (SelectedAsmItem != prevItem) - lbCode->Invalidate(); -} -// --------------------------------------------------------------------------- - -void __fastcall TFMain_11011981::pcInfoChange(TObject *Sender) { - switch (pcInfo->TabIndex) { - case 0: - WhereSearch = SEARCH_UNITS; - break; - case 1: - WhereSearch = SEARCH_RTTIS; - break; - case 2: - WhereSearch = SEARCH_FORMS; - break; - } -} -// --------------------------------------------------------------------------- - -void __fastcall TFMain_11011981::pcWorkAreaChange(TObject *Sender) { - switch (pcWorkArea->TabIndex) { - case 0: - WhereSearch = SEARCH_CODEVIEWER; - break; - case 1: - WhereSearch = SEARCH_CLASSVIEWER; - break; - case 2: - WhereSearch = SEARCH_STRINGS; - break; - case 3: - WhereSearch = SEARCH_NAMES; - break; - case 4: - WhereSearch = SEARCH_SOURCEVIEWER; - break; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchFormClick(TObject *Sender) { - WhereSearch = SEARCH_FORMS; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < FormsSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(FormsSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (lbForms->ItemIndex == -1) - FormsSearchFrom = 0; - else - FormsSearchFrom = lbForms->ItemIndex; - - FormsSearchText = FindDlg_11011981->cbText->Text; - if (FormsSearchList->IndexOf(FormsSearchText) == -1) - FormsSearchList->Add(FormsSearchText); - FindText(FormsSearchText); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchNameClick(TObject *Sender) { - WhereSearch = SEARCH_NAMES; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < NamesSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(NamesSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (lbNames->ItemIndex == -1) - NamesSearchFrom = 0; - else - NamesSearchFrom = lbNames->ItemIndex; - - NamesSearchText = FindDlg_11011981->cbText->Text; - if (NamesSearchList->IndexOf(NamesSearchText) == -1) - NamesSearchList->Add(NamesSearchText); - FindText(NamesSearchText); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miPluginsClick(TObject *Sender) { - String PluginsPath = AppDir + "Plugins"; - if (!DirectoryExists(PluginsPath)) { - if (!CreateDir(PluginsPath)) { - ShowMessage("Cannot create subdirectory for plugins"); - return; - } - } - - ResInfo->FormPluginName = ""; - if (ResInfo->hFormPlugin) { - FreeLibrary(ResInfo->hFormPlugin); - ResInfo->hFormPlugin = 0; - } - FPlugins->PluginsPath = PluginsPath; - FPlugins->PluginName = ""; - if (FPlugins->ShowModal() == mrOk) - ResInfo->FormPluginName = FPlugins->PluginName; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCopyStringsClick(TObject *Sender) { - Copy2Clipboard(lbStrings->Items, 0, false); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miViewAllClick(TObject *Sender) {; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbSourceCodeMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbSourceCode->CanFocus()) - ActiveControl = lbSourceCode; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::cbMultipleSelectionClick(TObject *Sender) { - // lbCode->MultiSelect = cbMultipleSelection->Checked; - // miSwitchFlag->Enabled = cbMultipleSelection->Checked; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbSourceCodeDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { - /* - if (hHighlight && HighlightDrawItem) - { - HighlightDrawItem(DelphiLbId, Index, Rect, false); - } - */ -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSwitchSkipFlagClick(TObject *Sender) { - DWORD _adr; - - if (lbCode->SelCount > 0) { - for (int n = 0; n < lbCode->Count; n++) { - if (lbCode->Selected[n]) { - sscanf(AnsiString(lbCode->Items->Strings[n]).c_str() + 2, "%lX", &_adr); - Flags[Adr2Pos(_adr)] ^= (cfDSkip | cfSkip); - } - } - RedrawCode(); - ProjectModified = true; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSwitchFrameFlagClick(TObject *Sender) { - DWORD _adr; - - if (lbCode->SelCount > 0) { - for (int n = 0; n < lbCode->Count; n++) { - if (lbCode->Selected[n]) { - sscanf(AnsiString(lbCode->Items->Strings[n]).c_str() + 2, "%lX", &_adr); - Flags[Adr2Pos(_adr)] ^= cfFrame; - } - } - RedrawCode(); - ProjectModified = true; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::cfTry1Click(TObject *Sender) { - DWORD _adr; - - if (lbCode->SelCount > 0) { - for (int n = 0; n < lbCode->Count; n++) { - if (lbCode->Selected[n]) { - sscanf(AnsiString(lbCode->Items->Strings[n]).c_str() + 2, "%lX", &_adr); - Flags[Adr2Pos(_adr)] ^= cfTry; - } - } - RedrawCode(); - ProjectModified = true; - } -} - -// --------------------------------------------------------------------------- -/* - void __fastcall TFMain_11011981::ChangeDelphiHighlightTheme(TObject *Sender) - { - TMenuItem* mi = (TMenuItem*)Sender; - ChangeTheme(DelphiLbId, mi->Tag); - } - //--------------------------------------------------------------------------- - */ -void __fastcall TFMain_11011981::miProcessDumperClick(TObject *Sender) { - FActiveProcesses->ShowModal(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbSourceCodeClick(TObject *Sender) { - WhereSearch = SEARCH_SOURCEVIEWER; - - if (lbSourceCode->ItemIndex <= 0) - return; - - String prevItem = SelectedSourceItem; - SelectedSourceItem = ""; - String text = lbSourceCode->Items->Strings[lbSourceCode->ItemIndex]; - int textLen = text.Length(); - - TPoint cursorPos; - GetCursorPos(&cursorPos); - cursorPos = lbSourceCode->ScreenToClient(cursorPos); - - for (int n = 1, wid = 0; n <= textLen; n++) { - int cwid = lbSourceCode->Canvas->TextWidth(text[n]); - if (wid > cursorPos.x) { - char c; - int beg = n - 1; - while (beg >= 1) { - c = text[beg]; - if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.') { - beg++; - break; - } - beg--; - } - int end = beg; - while (end <= textLen) { - c = text[end]; - if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.') { - end--; - break; - } - end++; - } - SelectedSourceItem = text.SubString(beg, end - beg + 1); - break; - } - wid += cwid; - } - if (SelectedSourceItem != prevItem) - lbSourceCode->Invalidate(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSetlvartypeClick(TObject *Sender) { - PInfoRec recN = GetInfoRec(CurProcAdr); - PLOCALINFO pLocInfo = recN->procInfo->GetLocal(SelectedSourceItem); - if (recN && recN->procInfo->locals && SelectedSourceItem != "") { - String ftype = InputDialogExec("Enter Type of " + SelectedSourceItem, "Type", pLocInfo->TypeDef).Trim(); - pLocInfo->TypeDef = ftype; - recN->procInfo->SetLocalType(pLocInfo->Ofs, ftype); - bDecompileClick(this); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmSourceCodePopup(TObject *Sender) { - PLOCALINFO pLocalInfo; - - PInfoRec recN = GetInfoRec(CurProcAdr); - if (recN && recN->procInfo->locals && SelectedSourceItem != "") - pLocalInfo = recN->procInfo->GetLocal(SelectedSourceItem); - - miSetlvartype->Enabled = (pLocalInfo); -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Tab Names -// *************************************************************************** -// --------------------------------------------------------------------------- - -void __fastcall TFMain_11011981::ShowNames(int idx) { - int n, wid, maxwid = 0; - PInfoRec recN; - String line; - TCanvas* canvas = lbNames->Canvas; - - lbNames->Clear(); - lbNames->Items->BeginUpdate(); - - for (n = CodeSize; n < TotalSize; n++) { - if (IsFlagSet(cfImport, n)) - continue; - recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->HasName()) { - line = Val2Str8(Pos2Adr(n)) + " " + recN->GetName(); - if (recN->type != "") - line += ":" + recN->type; - lbNames->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - } - for (n = 0; n < BSSInfos->Count; n++) { - recN = (PInfoRec)BSSInfos->Objects[n]; - line = BSSInfos->Strings[n] + " " + recN->GetName(); - if (recN->type != "") - line += ":" + recN->type; - lbNames->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - lbNames->Items->EndUpdate(); - - lbNames->ItemIndex = idx; - lbNames->ScrollWidth = maxwid + 2; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowNameXrefs(DWORD Adr, int selIdx) { - PInfoRec recN; - - lbNXrefs->Clear(); - - recN = GetInfoRec(Adr); - if (recN && recN->xrefs) { - int wid, maxwid = 0; - TCanvas *canvas = lbNXrefs->Canvas; - DWORD pAdr = 0; - char f = 2; - - lbNXrefs->Items->BeginUpdate(); - for (int m = 0; m < recN->xrefs->Count; m++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; - String line = " " + Val2Str8(recX->adr + recX->offset) + " " + recX->type; - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - PUnitRec recU = GetUnit(recX->adr); - if (recU && recU->kb) - line[1] ^= 1; - if (pAdr != recX->adr) - f ^= 2; - line[1] ^= f; - pAdr = recX->adr; - lbNXrefs->Items->Add(line); - } - lbNXrefs->Items->EndUpdate(); - - lbNXrefs->ScrollWidth = maxwid + 2; - lbNXrefs->ItemIndex = selIdx; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbNamesClick(TObject *Sender) { - // NamesSearchFrom = lbNames->ItemIndex; - // WhereSearch = SEARCH_NAMES; - - if (lbNames->ItemIndex >= 0) { - DWORD adr; - String line = lbNames->Items->Strings[lbNames->ItemIndex]; - sscanf(AnsiString(line).c_str() + 1, "%lX", &adr); - ShowNameXrefs(adr, -1); - } -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Tab Units -// *************************************************************************** -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSortUnitsByAdrClick(TObject *Sender) { - miSortUnitsByAdr->Checked = true; - miSortUnitsByOrd->Checked = false; - miSortUnitsByNam->Checked = false; - UnitSortField = 0; - ShowUnits(true); - lbUnits->SetFocus(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSortUnitsByOrdClick(TObject *Sender) { - miSortUnitsByAdr->Checked = false; - miSortUnitsByOrd->Checked = true; - miSortUnitsByNam->Checked = false; - UnitSortField = 1; - ShowUnits(true); - lbUnits->SetFocus(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSortUnitsByNamClick(TObject *Sender) { - miSortUnitsByAdr->Checked = false; - miSortUnitsByOrd->Checked = false; - miSortUnitsByNam->Checked = true; - UnitSortField = 2; - ShowUnits(true); - lbUnits->SetFocus(); -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::ContainsUnexplored(PUnitRec recU) { - if (!recU) - return false; - - bool unk = false; - for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) { - int n = Adr2Pos(adr); - if (!Flags[n]) { - BYTE b0 = *(Code + n); - if (!unk) { - BYTE b1 = *(Code + n + 1); - BYTE b2 = *(Code + n + 2); - if ((adr & 3) == 3 && (b0 == 0 || b0 == 0x90)) - continue; - if ((adr & 3) == 2 && ((b0 == 0 && b1 == 0) || (b0 == 0x8B && b1 == 0xC0))) { - adr++; - continue; - } - if ((adr & 3) == 1 && ((b0 == 0 && b1 == 0 && b2 == 0) || (b0 == 0x8D && b1 == 0x40 && b2 == 0))) { - adr += 2; - continue; - } - unk = true; - } - continue; - } - - if (unk) - return true; - } - return false; -} -// --------------------------------------------------------------------------- -#define TRIV_UNIT 1 //Trivial unit -#define USER_UNIT 2 //User unit -#define UNEXP_UNIT 4 //Unit has undefined bytes - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowUnits(bool showUnk) { - int oldItemIdx = lbUnits->ItemIndex; - DWORD selAdr = 0; - if (oldItemIdx != -1) { - String item = lbUnits->Items->Strings[oldItemIdx]; - sscanf(AnsiString(item).c_str() + 1, "%lX", &selAdr); - } - int oldTopIdx = lbUnits->TopIndex; - - lbUnits->Clear(); - lbUnits->Items->BeginUpdate(); - - if (UnitsNum) { - switch (UnitSortField) { - case 0: - Units->Sort(SortUnitsByAdr); - break; - case 1: - Units->Sort(SortUnitsByOrd); - break; - case 2: - Units->Sort(SortUnitsByNam); - break; - } - } - - int stringLen; - int newItemIdx = -1; - int wid, maxwid = 0; - TCanvas *canvas = lbUnits->Canvas; - char ci, cf, orderS[256]; - - for (int i = 0; i < UnitsNum; i++) { - PUnitRec recU = (UnitRec*)Units->Items[i]; - if (recU->fromAdr == selAdr) - newItemIdx = i; - ci = (!recU->trivialIni) ? 'I' : ' '; - cf = (!recU->trivialFin) ? 'F' : ' '; - stringLen = sprintf(StringBuf, " %08lX #%03d %c%c ", (int)recU->fromAdr, recU->iniOrder, ci, cf); - if (recU->names->Count) { - for (int u = 0; u < recU->names->Count; u++) { - if (stringLen + recU->names->Strings[u].Length() >= 256) { - stringLen += sprintf(StringBuf + stringLen, "..."); - break; - } - if (u) { - StringBuf[stringLen] = ';'; - stringLen++; - } - stringLen += sprintf(StringBuf + stringLen, "%s", recU->names->Strings[u].c_str()); - } - } - else - stringLen += sprintf(StringBuf + stringLen, "_Unit%d", recU->iniOrder); - - if (i != UnitsNum - 1) { - // Trivial units - if (recU->trivial) - StringBuf[0] = TRIV_UNIT; - else if (!recU->kb) - StringBuf[0] = USER_UNIT; - } - // Last unit is user's - else - StringBuf[0] = USER_UNIT; - - // Unit has undefined bytes - if (showUnk && ContainsUnexplored(recU)) - StringBuf[0] |= UNEXP_UNIT; - String line = String(StringBuf, stringLen); - lbUnits->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - if (newItemIdx == -1) - lbUnits->TopIndex = oldTopIdx; - else { - if (newItemIdx != oldItemIdx) { - lbUnits->ItemIndex = newItemIdx; - int newTopIdx = newItemIdx - (oldItemIdx - oldTopIdx); - if (newTopIdx < 0) - newTopIdx = 0; - lbUnits->TopIndex = newTopIdx; - } - else { - lbUnits->ItemIndex = newItemIdx; - lbUnits->TopIndex = oldTopIdx; - } - } - lbUnits->ItemHeight = lbUnits->Canvas->TextHeight("T"); - lbUnits->ScrollWidth = maxwid + 2; - lbUnits->Items->EndUpdate(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbUnits->CanFocus()) - ActiveControl = lbUnits; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitsClick(TObject *Sender) { - UnitsSearchFrom = lbUnits->ItemIndex; - WhereSearch = SEARCH_UNITS; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitsDblClick(TObject *Sender) { - DWORD adr; - - String item = lbUnits->Items->Strings[lbUnits->ItemIndex]; - sscanf(AnsiString(item).c_str() + 1, "%lX", &adr); - PUnitRec recU = GetUnit(adr); - - if (!CurUnitAdr || adr != CurUnitAdr) { - CurUnitAdr = adr; - ShowUnitItems(recU, 0, -1); - } - else { - ShowUnitItems(recU, lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - } - - CurUnitAdr = adr; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_RETURN) - lbUnitsDblClick(Sender); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { - char *s, *pos; - int flags, len; - TColor _color; - TListBox *lb; - TCanvas *canvas; - String text, str1, str2; - - lb = (TListBox*)Control; - canvas = lb->Canvas; - SaveCanvas(canvas); - - if (Index < lb->Count) { - flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); - if (!Control->UseRightToLeftAlignment()) - Rect.Left += 2; - else - Rect.Right -= 2; - - text = lb->Items->Strings[Index]; - // lb->ItemHeight = canvas->TextHeight(text); - canvas->FillRect(Rect); - - s = AnsiString(text).c_str(); - // *XXXXXXXX #XXX XX NAME - pos = strrchr(s, ' '); - len = pos - s; - str1 = text.SubString(2, len - 1); - str2 = text.SubString(len + 1, text.Length() - len); - - if (!State.Contains(odSelected)) - _color = TColor(0); // Black - else - _color = TColor(0xBBBBBB); // LightGray - Rect.Right = Rect.Left; - DrawOneItem(str1, canvas, Rect, _color, flags); - - // Unit name - // Trivial unit - red - if (text[1] & TRIV_UNIT) { - if (!State.Contains(odSelected)) - _color = TColor(0x0000B0); // Red - else - _color = TColor(0xBBBBBB); // LightGray - } - else { - // User unit - green - if (text[1] & USER_UNIT) { - if (!State.Contains(odSelected)) { - if (text[1] & UNEXP_UNIT) - _color = TColor(0xC0C0FF); // Light Red - else - _color = TColor(0x00B000); // Green - } - else - _color = TColor(0xBBBBBB); // LightGray - } - // From knowledge base - blue - else { - if (!State.Contains(odSelected)) - _color = TColor(0xC08000); // Blue - else - _color = TColor(0xBBBBBB); // LightGray - } - } - DrawOneItem(str2, canvas, Rect, _color, flags); - } - RestoreCanvas(canvas); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchUnitClick(TObject *Sender) { - WhereSearch = SEARCH_UNITS; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < UnitsSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(UnitsSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (lbUnits->ItemIndex == -1) - UnitsSearchFrom = 0; - else - UnitsSearchFrom = lbUnits->ItemIndex; - - UnitsSearchText = FindDlg_11011981->cbText->Text; - if (UnitsSearchList->IndexOf(UnitsSearchText) == -1) - UnitsSearchList->Add(UnitsSearchText); - FindText(UnitsSearchText); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miRenameUnitClick(TObject *Sender) { - if (lbUnits->ItemIndex == -1) - return; - - String item = lbUnits->Items->Strings[lbUnits->ItemIndex]; - DWORD adr; - sscanf(AnsiString(item).c_str() + 1, "%lX", &adr); - PUnitRec recU = GetUnit(adr); - - String text = ""; - for (int u = 0; u < recU->names->Count; u++) { - if (u) - text += "+"; - text += recU->names->Strings[u]; - } - String sName = InputDialogExec("Enter UnitName", "Name:", text); - if (sName != "") { - recU->names->Clear(); - SetUnitName(recU, sName); - - ProjectModified = true; - ShowUnits(true); - lbUnits->SetFocus(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowUnitItems(PUnitRec recU, int topIdx, int itemIdx) { - bool unk = false; - bool imp, exp, emb, xref; - int wid, maxwid = 0; - TCanvas *canvas = lbUnitItems->Canvas; - String line, prefix; - - if (!CurUnitAdr) - return; - - // if (AnalyzeThread) AnalyzeThread->Suspend(); - - lbUnitItems->Clear(); - lbUnitItems->Items->BeginUpdate(); - - for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) { - int unknum, pos = Adr2Pos(adr); - if (!IsFlagSet(~cfLoc, pos)) { - BYTE b0 = *(Code + pos); - if (!unk) { - unknum = 0; - BYTE b1 = *(Code + pos + 1); - BYTE b2 = *(Code + pos + 2); - if ((adr & 3) == 3 && (b0 == 0 || b0 == 0x90)) - continue; - if ((adr & 3) == 2 && ((b0 == 0 && b1 == 0) || (b0 == 0x8B && b1 == 0xC0) || (b0 == 0x90 && b1 == 0x90))) { - adr++; - continue; - } - if ((adr & 3) == 1 && ((b0 == 0 && b1 == 0 && b2 == 0) || (b0 == 0x8D && b1 == 0x40 && b2 == 0) || (b0 == 0x90 && b1 == 0x90 && b2 == 0x90))) { - adr += 2; - continue; - } - line = " " + Val2Str8(adr) + " ????"; - line[1] ^= 1; - line += " " + Val2Str2(b0); - unknum++; - unk = true; - } - else { - if (unknum <= 16) { - if (unknum == 16) - line += "..."; - else - line += " " + Val2Str2(b0); - unknum++; - } - } - continue; - } - - if (unk) { - lbUnitItems->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - unk = false; - } - - if (adr == recU->iniadr) - continue; - if (adr == recU->finadr) - continue; - - // EP - if (adr == EP) { - line = " " + Val2Str8(adr) + " EntryPoint"; - lbUnitItems->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - continue; - } - - PInfoRec recN = GetInfoRec(adr); - if (!recN) - continue; - - BYTE kind = recN->kind; - // Skip calls, that are in the body of some asm-procs (for example, FloatToText from SysUtils) - // if (kind >= ikRefine && kind <= ikFunc && recN->procInfo && IsFlagSet(cfImport, pos)) continue; - - imp = IsFlagSet(cfImport, pos); - exp = IsFlagSet(cfExport, pos); - emb = false; - if (IsFlagSet(cfProcStart, pos)) { - if (recN->procInfo) { - emb = (recN->procInfo->flags & PF_EMBED); - } - } - xref = false; - - line = ""; - - switch (kind) { - case ikInteger: - case ikChar: - case ikEnumeration: - case ikFloat: - case ikSet: - case ikClass: - case ikMethod: - case ikWChar: - case ikLString: - case ikVariant: - case ikArray: - case ikRecord: - case ikInterface: - case ikInt64: - case ikDynArray: - case ikUString: - case ikClassRef: - case ikPointer: - case ikProcedure: - line = "<" + TypeKind2Name(kind) + "> "; - if (recN->HasName()) { - if (recN->GetNameLength() <= MAXLEN) - line += recN->GetName(); - else { - line += recN->GetName().SubString(1, MAXLEN) + "..."; - } - } - break; - case ikString: - if (!IsFlagSet(cfRTTI, pos)) - line = " "; - else - line = "<" + TypeKind2Name(kind) + "> "; - if (recN->HasName()) { - if (recN->GetNameLength() <= MAXLEN) - line += recN->GetName(); - else { - line += recN->GetName().SubString(1, MAXLEN) + "..."; - } - } - break; - case ikWString: - line = " "; - if (recN->HasName()) { - if (recN->GetNameLength() <= MAXLEN) - line += recN->GetName(); - else { - line += recN->GetName().SubString(1, MAXLEN) + "..."; - } - } - break; - case ikCString: - line = " "; - if (recN->HasName()) { - if (recN->GetNameLength() <= MAXLEN) - line += recN->GetName(); - else { - line += recN->GetName().SubString(1, MAXLEN) + "..."; - } - } - break; - case ikWCString: - line = " "; - if (recN->HasName()) { - if (recN->GetNameLength() <= MAXLEN) - line += recN->GetName(); - else { - line += recN->GetName().SubString(1, MAXLEN) + "..."; - } - } - break; - case ikResString: - if (recN->HasName()) - line += " " + recN->GetName() + "=" + recN->rsInfo->value; - break; - case ikVMT: - line = " "; - if (recN->HasName()) - line += recN->GetName(); - break; - case ikConstructor: - xref = true; - line = " " + recN->MakePrototype(adr, false, true, false, true, false); - break; - case ikDestructor: - xref = true; - line = " " + recN->MakePrototype(adr, false, true, false, true, false); - break; - case ikProc: - xref = true; - line = "<"; - if (imp) - line += "Imp"; - else if (exp) - line += "Exp"; - else if (emb) - line += "Emb"; - line += "Proc> " + recN->MakePrototype(adr, false, true, false, true, false); - break; - case ikFunc: - xref = true; - line = "<"; - if (imp) - line += "Imp"; - else if (exp) - line += "Exp"; - else if (emb) - line += "Emb"; - line += "Func> " + recN->MakePrototype(adr, false, true, false, true, false); - break; - case ikGUID: - line = " "; - if (recN->HasName()) - line += recN->GetName(); - break; - case ikRefine: - xref = true; - line = "<"; - if (imp) - line += "Imp"; - else if (exp) - line += "Exp"; - else if (emb) - line += "Emb"; - line += "?> " + recN->MakePrototype(adr, false, true, false, true, false); - break; - default: - if (IsFlagSet(cfProcStart, pos)) { - xref = true; - if (recN->kind == ikConstructor) - line = " " + recN->MakePrototype(adr, false, true, false, true, false); - else if (recN->kind == ikDestructor) - line = " " + recN->MakePrototype(adr, false, true, false, true, false); - else { - line = "<"; - if (emb) - line += "Emb"; - line += "Proc> " + recN->MakePrototype(adr, false, true, false, true, false); - } - } - break; - } - - if (kind >= ikRefine && kind <= ikFunc) { - if (recN->procInfo->flags & PF_VIRTUAL) - line += " virtual"; - if (recN->procInfo->flags & PF_DYNAMIC) - line += " dynamic"; - if (recN->procInfo->flags & PF_EVENT) - line += " event"; - } - if (line != "") { - prefix = " " + Val2Str8(adr); - if (xref && recN->xrefs && recN->xrefs->Count) { - prefix[1] ^= 2; - for (int m = 0; m < recN->xrefs->Count; m++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; - PUnitRec recU = GetUnit(recX->adr); - if (recU && !recU->kb) { - prefix[1] ^= 4; - break; - } - } - prefix += " " + String(recN->xrefs->Count); - if (recN->xrefs->Count <= 9) - prefix += " "; - else if (recN->xrefs->Count <= 99) - prefix += " "; - } - line = prefix + " " + line; - lbUnitItems->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - } - - // Add initialization procedure - if (recU->iniadr) { - line = " " + Val2Str8(recU->iniadr) + " Initialization;"; - lbUnitItems->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - // Add finalization procedure - if (recU->finadr) { - line = " " + Val2Str8(recU->finadr) + " Finalization;"; - lbUnitItems->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - lbUnitItems->TopIndex = topIdx; - lbUnitItems->ItemIndex = itemIdx; - lbUnitItems->ScrollWidth = maxwid + 2; - lbUnitItems->ItemHeight = lbUnitItems->Canvas->TextHeight("T"); - lbUnitItems->Items->EndUpdate(); - - // if (AnalyzeThread) AnalyzeThread->Resume(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitItemsDblClick(TObject *Sender) { - int idx = -1, len, size, refCnt, pos, bytes = 1024; - WORD* uses; - DWORD adr; - char *tmpBuf; - PInfoRec recN; - MTypeInfo tInfo; - String str; - char tkName[32], typeName[1024]; - - if (lbUnitItems->ItemIndex == -1) - return; - - String item = lbUnitItems->Items->Strings[lbUnitItems->ItemIndex]; - // Xrefs? - if (item[11] == '<' || item[11] == '?') - sscanf(AnsiString(item).c_str() + 1, "%lX%s%s", &adr, tkName, typeName); - else - sscanf(AnsiString(item).c_str() + 1, "%lX%d%s%s", &adr, &refCnt, tkName, typeName); - String name = String(tkName); - pos = Adr2Pos(adr); - - if (SameText(name, "????")) { - // Find end of unexplored Data - // Get first byte (use later for filtering code?data) - BYTE db = *(Code + pos); - - FExplorer_11011981->tsCode->TabVisible = true; - FExplorer_11011981->ShowCode(adr, bytes); - FExplorer_11011981->tsData->TabVisible = true; - FExplorer_11011981->ShowData(adr, bytes); - FExplorer_11011981->tsString->TabVisible = true; - FExplorer_11011981->ShowString(adr, 1024); - FExplorer_11011981->tsText->TabVisible = false; - FExplorer_11011981->WAlign = 0; - - FExplorer_11011981->btnDefCode->Enabled = true; - if (IsFlagSet(cfCode, pos)) - FExplorer_11011981->btnDefCode->Enabled = false; - FExplorer_11011981->btnUndefCode->Enabled = false; - if (IsFlagSet(cfCode | cfData, pos)) - FExplorer_11011981->btnUndefCode->Enabled = true; - - if (IsValidCode(adr) != -1 && db >= 0xF) - FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsCode; - else - FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsData; - - if (FExplorer_11011981->ShowModal() == mrOk) { - switch (FExplorer_11011981->DefineAs) { - case DEFINE_AS_CODE: - recN = GetInfoRec(adr); - if (!recN) - recN = new InfoRec(pos, ikRefine); - else if (recN->kind < ikRefine || recN->kind > ikFunc) { - delete recN; - recN = new InfoRec(pos, ikRefine); - } - - // AnalyzeProcInitial(adr); - AnalyzeProc1(adr, 0, 0, 0, false); - AnalyzeProc2(adr, true, true); - AnalyzeArguments(adr); - AnalyzeProc2(adr, true, true); - - if (!ContainsUnexplored(GetUnit(adr))) - ShowUnits(true); - ShowUnitItems(GetUnit(adr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); - ShowCode(adr, 0, -1, -1); - break; - case DEFINE_AS_STRING: - break; - } - } - return; - } - - if (SameText(name, "") && tsClassView->TabVisible) { - ShowClassViewer(adr); - return; - } - if (IsFlagSet(cfRTTI, pos)) { - FTypeInfo_11011981->ShowRTTI(adr); - return; - } - if (SameText(name, "")) { - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->Caption = "ResString"; - recN = GetInfoRec(adr); - FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); - FStringInfo_11011981->ShowModal(); - return; - } - if (SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "")) { - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->Caption = "String"; - recN = GetInfoRec(adr); - FStringInfo_11011981->memStringInfo->Lines->Add(recN->GetName()); - FStringInfo_11011981->ShowModal(); - return; - } - if (SameText(name, "")) { - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->Caption = "String"; - recN = GetInfoRec(adr); - len = wcslen((wchar_t*)(Code + Adr2Pos(adr))); - size = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)(Code + Adr2Pos(adr)), len, 0, 0, 0, 0); - if (size) { - tmpBuf = new char[size + 1]; - WideCharToMultiByte(CP_ACP, 0, (wchar_t*)(Code + Adr2Pos(adr)), len, tmpBuf, len, 0, 0); - FStringInfo_11011981->memStringInfo->Lines->Add(String(tmpBuf, len)); - delete[]tmpBuf; - FStringInfo_11011981->ShowModal(); - } - return; - } - /* - if (SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "") || - SameText(name, "")) - { - uses = KnowledgeBase.GetTypeUses(typeName); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, typeName); - if (uses) delete[] uses; - - if (idx != -1) - { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS, &tInfo)) - { - FTypeInfo_11011981->ShowKbInfo(&tInfo); - //as delete tInfo; - } - } - else - { - FTypeInfo_11011981->ShowRTTI(adr); - } - return; - } - */ - if (SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || - SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || SameText(name, "") || - SameText(name, "") || SameText(name, "")) { - PROCHISTORYREC rec; - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(adr, 0, -1, -1); - CodeHistoryPush(&rec); - pcWorkArea->ActivePage = tsCodeView; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitItemsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_RETURN) - lbUnitItemsDblClick(Sender); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitItemsClick(TObject *Sender) { - UnitItemsSearchFrom = lbUnitItems->ItemIndex; - WhereSearch = SEARCH_UNITITEMS; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitItemsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { - int flags; - TColor _color; - TListBox *lb; - TCanvas *canvas; - String text, str; - - lb = (TListBox*)Control; - canvas = lb->Canvas; - SaveCanvas(canvas); - - if (Index < lb->Count) { - flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); - if (!Control->UseRightToLeftAlignment()) - Rect.Left += 2; - else - Rect.Right -= 2; - canvas->FillRect(Rect); - - text = lb->Items->Strings[Index]; - // lb->ItemHeight = canvas->TextHeight(text); - str = text.SubString(2, text.Length() - 1); - // Procs with Xrefs - if (text[1] & 6) { - // Xrefs from user units - if (text[1] & 4) { - if (!State.Contains(odSelected)) - _color = TColor(0x00B000); // Green - else - _color = TColor(0xBBBBBB); // LightGray - } - // No Xrefs from user units, only from KB units - else { - if (!State.Contains(odSelected)) - _color = TColor(0xC08000); // Blue - else - _color = TColor(0xBBBBBB); // LightGray - } - } - // Unresolved items - else if (text[1] & 1) { - if (!State.Contains(odSelected)) - _color = TColor(0x8080FF); // Red - else - _color = TColor(0xBBBBBB); // LightGray - } - // Other - else { - if (!State.Contains(odSelected)) - _color = TColor(0); // Black - else - _color = TColor(0xBBBBBB); // LightGray - } - Rect.Right = Rect.Left; - DrawOneItem(str, canvas, Rect, _color, flags); - } - RestoreCanvas(canvas); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbUnitItemsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbUnitItems->CanFocus()) - ActiveControl = lbUnitItems; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchItemClick(TObject *Sender) { - WhereSearch = SEARCH_UNITITEMS; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < UnitItemsSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(UnitItemsSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (lbUnitItems->ItemIndex < 0) - UnitItemsSearchFrom = 0; - else - UnitItemsSearchFrom = lbUnitItems->ItemIndex; - - UnitItemsSearchText = FindDlg_11011981->cbText->Text; - if (UnitItemsSearchList->IndexOf(UnitItemsSearchText) == -1) - UnitItemsSearchList->Add(UnitItemsSearchText); - FindText(UnitItemsSearchText); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miEditFunctionIClick(TObject *Sender) { - int refCnt; - DWORD adr; - char tkName[32]; - - if (lbUnitItems->ItemIndex < 0) - return; - - String item = lbUnitItems->Items->Strings[lbUnitItems->ItemIndex]; - // Xrefs? - if (item[11] == '<' || item[11] == '?') - sscanf(AnsiString(item).c_str() + 1, "%lX%s", &adr, tkName); - else - sscanf(AnsiString(item).c_str() + 1, "%lX%d%s", &adr, &refCnt, tkName); - - String name = String(tkName); - - if (SameText(name, "") || - // SameText(name, "") || - // SameText(name, "") || - SameText(name, "") || SameText(name, "") || SameText(name, "") || - // SameText(name, "") || - SameText(name, "") // || - // SameText(name, "") || - // SameText(name, "") || - // SameText(name, "") - ) { - EditFunction(adr); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miCopyAddressIClick(TObject *Sender) { - CopyAddress(lbUnitItems->Items->Strings[lbUnitItems->ItemIndex], 1, 8); -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Tab RTTIs -// *************************************************************************** -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -int __fastcall SortRTTIsByAdr(void *item1, void *item2) { - PTypeRec rec1 = (PTypeRec)item1; - PTypeRec rec2 = (PTypeRec)item2; - if (rec1->adr > rec2->adr) - return 1; - if (rec1->adr < rec2->adr) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall SortRTTIsByKnd(void *item1, void *item2) { - PTypeRec rec1 = (PTypeRec)item1; - PTypeRec rec2 = (PTypeRec)item2; - if (rec1->kind > rec2->kind) - return 1; - if (rec1->kind < rec2->kind) - return -1; - return CompareText(rec1->name, rec2->name); -} - -// --------------------------------------------------------------------------- -int __fastcall SortRTTIsByNam(void *item1, void *item2) { - PTypeRec rec1 = (PTypeRec)item1; - PTypeRec rec2 = (PTypeRec)item2; - return CompareText(rec1->name, rec2->name); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowRTTIs() { - lbRTTIs->Clear(); - // as - lbRTTIs->Items->BeginUpdate(); - - if (OwnTypeList->Count) { - switch (RTTISortField) { - case 0: - OwnTypeList->Sort(SortRTTIsByAdr); - break; - case 1: - OwnTypeList->Sort(SortRTTIsByKnd); - break; - case 2: - OwnTypeList->Sort(SortRTTIsByNam); - break; - } - } - - int wid, maxwid = 0; - TCanvas *canvas = lbUnits->Canvas; - String line; - for (int n = 0; n < OwnTypeList->Count; n++) { - PTypeRec recT = (PTypeRec)OwnTypeList->Items[n]; - if (recT->kind == ikVMT) - line = Val2Str8(recT->adr) + " " + recT->name; - else - line = Val2Str8(recT->adr) + " <" + TypeKind2Name(recT->kind) + "> " + recT->name; - lbRTTIs->Items->Add(line); - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - } - lbRTTIs->Items->EndUpdate(); - - lbRTTIs->ScrollWidth = maxwid + 2; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbRTTIsDblClick(TObject *Sender) { - DWORD adr; - char tkName[32], typeName[1024]; - - sscanf(AnsiString(lbRTTIs->Items->Strings[lbRTTIs->ItemIndex]).c_str(), "%lX%s%s", &adr, tkName, typeName); - String name = String(tkName); - - if (SameText(name, "") && tsClassView->TabVisible) { - ShowClassViewer(adr); - return; - } - - FTypeInfo_11011981->ShowRTTI(adr); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbRTTIsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbRTTIs->CanFocus()) - ActiveControl = lbRTTIs; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbRTTIsClick(TObject *Sender) { - RTTIsSearchFrom = lbRTTIs->ItemIndex; - WhereSearch = SEARCH_RTTIS; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbRTTIsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_RETURN) - lbRTTIsDblClick(Sender); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchRTTIClick(TObject *Sender) { - WhereSearch = SEARCH_RTTIS; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < RTTIsSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(RTTIsSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (lbRTTIs->ItemIndex < 0) - RTTIsSearchFrom = 0; - else - RTTIsSearchFrom = lbRTTIs->ItemIndex; - - RTTIsSearchText = FindDlg_11011981->cbText->Text; - if (RTTIsSearchList->IndexOf(RTTIsSearchText) == -1) - RTTIsSearchList->Add(RTTIsSearchText); - FindText(RTTIsSearchText); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmRTTIsPopup(TObject *Sender) { - if (lbRTTIs->ItemIndex < 0) - return; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSortRTTIsByAdrClick(TObject *Sender) { - miSortRTTIsByAdr->Checked = true; - miSortRTTIsByKnd->Checked = false; - miSortRTTIsByNam->Checked = false; - RTTISortField = 0; - ShowRTTIs(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSortRTTIsByKndClick(TObject *Sender) { - miSortRTTIsByAdr->Checked = false; - miSortRTTIsByKnd->Checked = true; - miSortRTTIsByNam->Checked = false; - RTTISortField = 1; - ShowRTTIs(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSortRTTIsByNamClick(TObject *Sender) { - miSortRTTIsByAdr->Checked = false; - miSortRTTIsByKnd->Checked = false; - miSortRTTIsByNam->Checked = true; - RTTISortField = 2; - ShowRTTIs(); -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Tab Strings -// *************************************************************************** -// --------------------------------------------------------------------------- - -void __fastcall TFMain_11011981::ShowStrings(int idx) { - int n, itemidx, wid, maxwid = 0; - PInfoRec recN; - String line, line1, str; - TCanvas* canvas = lbStrings->Canvas; - - lbStrings->Clear(); - lbStrings->Items->BeginUpdate(); - - for (n = 0; n < CodeSize; n++) { - recN = GetInfoRec(Pos2Adr(n)); - if (recN && !IsFlagSet(cfRTTI, n)) { - if (recN->kind == ikResString && recN->rsInfo->value != "") { - line = " " + Val2Str8(Pos2Adr(n)) + " " + recN->rsInfo->value; - if (recN->rsInfo->value.Length() <= MAXLEN) - line1 = line; - else { - line1 = line.SubString(1, MAXLEN) + "..."; - line1[1] ^= 1; - } - lbStrings->Items->Add(line1); - wid = canvas->TextWidth(line1); - if (wid > maxwid) - maxwid = wid; - continue; - } - if (recN->HasName()) { - switch (recN->kind) { - case ikString: - str = ""; - break; - case ikLString: - str = ""; - break; - case ikWString: - str = ""; - break; - case ikCString: - str = ""; - break; - case ikWCString: - str = ""; - break; - case ikUString: - str = ""; - break; - default: - str = ""; - break; - } - if (str != "") { - line = " " + Val2Str8(Pos2Adr(n)) + " " + str + " " + recN->GetName(); - if (recN->GetNameLength() <= MAXLEN) - line1 = line; - else { - line1 = line.SubString(1, MAXLEN) + "..."; - line1[1] ^= 1; - } - lbStrings->Items->Add(line1); - wid = canvas->TextWidth(line1); - if (wid > maxwid) - maxwid = wid; - } - } - } - } - lbStrings->ItemIndex = idx; - lbStrings->ScrollWidth = maxwid + 2; - lbStrings->ItemHeight = lbStrings->Canvas->TextHeight("T"); - lbStrings->Items->EndUpdate(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbStringsClick(TObject *Sender) { - StringsSearchFrom = lbStrings->ItemIndex; - WhereSearch = SEARCH_STRINGS; - - if (lbStrings->ItemIndex >= 0) { - DWORD adr; - String line = lbStrings->Items->Strings[lbStrings->ItemIndex]; - sscanf(AnsiString(line).c_str() + 1, "%lX", &adr); - ShowStringXrefs(adr, -1); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbStringsDblClick(TObject *Sender) { - DWORD adr; - String line = lbStrings->Items->Strings[lbStrings->ItemIndex]; - sscanf(AnsiString(line).c_str() + 1, "%lX", &adr); - if (IsValidImageAdr(adr)) { - PInfoRec recN = GetInfoRec(adr); - - if (recN->kind == ikResString) { - FStringInfo_11011981->Caption = "ResString context"; - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); - FStringInfo_11011981->ShowModal(); - } - else { - FStringInfo_11011981->Caption = "String context"; - FStringInfo_11011981->memStringInfo->Clear(); - FStringInfo_11011981->memStringInfo->Lines->Add(recN->GetName()); - FStringInfo_11011981->ShowModal(); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbStringsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { - int flags; - TColor _color; - TListBox *lb; - TCanvas *canvas; - String text, str; - - lb = (TListBox*)Control; - canvas = lb->Canvas; - SaveCanvas(canvas); - - if (Index < lb->Count) { - flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); - if (!Control->UseRightToLeftAlignment()) - Rect.Left += 2; - else - Rect.Right -= 2; - canvas->FillRect(Rect); - - text = lb->Items->Strings[Index]; - // lb->ItemHeight = canvas->TextHeight(text); - str = text.SubString(2, text.Length() - 1); - - // Long strings - if (text[1] & 1) - _color = TColor(0xBBBBBB); // LightGray - else - _color = TColor(0); // Black - - Rect.Right = Rect.Left; - DrawOneItem(str, canvas, Rect, _color, flags); - } - RestoreCanvas(canvas); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::miSearchStringClick(TObject *Sender) { - WhereSearch = SEARCH_STRINGS; - - FindDlg_11011981->cbText->Clear(); - for (int n = 0; n < StringsSearchList->Count; n++) - FindDlg_11011981->cbText->AddItem(StringsSearchList->Strings[n], 0); - - if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") { - if (lbStrings->ItemIndex < 0) - StringsSearchFrom = 0; - else - StringsSearchFrom = lbStrings->ItemIndex; - - StringsSearchText = FindDlg_11011981->cbText->Text; - if (StringsSearchList->IndexOf(StringsSearchText) == -1) - StringsSearchList->Add(StringsSearchText); - FindText(StringsSearchText); - - DWORD adr; - String line = lbStrings->Items->Strings[lbStrings->ItemIndex]; - sscanf(AnsiString(line).c_str() + 1, "%lX", &adr); - ShowStringXrefs(adr, -1); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbStringsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - if (lbStrings->CanFocus()) - ActiveControl = lbStrings; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowSXrefsClick(TObject *Sender) { - if (lbSXrefs->Visible) { - ShowSXrefs->BevelOuter = bvRaised; - lbSXrefs->Visible = false; - } - else { - ShowSXrefs->BevelOuter = bvLowered; - lbSXrefs->Visible = true; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowStringXrefs(DWORD Adr, int selIdx) { - lbSXrefs->Clear(); - - PInfoRec recN = GetInfoRec(Adr); - if (recN && recN->xrefs) { - int wid, maxwid = 0; - TCanvas *canvas = lbSXrefs->Canvas; - DWORD pAdr = 0; - char f = 2; - - lbSXrefs->Items->BeginUpdate(); - for (int m = 0; m < recN->xrefs->Count; m++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; - String line = " " + Val2Str8(recX->adr + recX->offset) + " " + recX->type; - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - PUnitRec recU = GetUnit(recX->adr); - if (recU && recU->kb) - line[1] ^= 1; - if (pAdr != recX->adr) - f ^= 2; - line[1] ^= f; - pAdr = recX->adr; - lbSXrefs->Items->Add(line); - } - lbSXrefs->Items->EndUpdate(); - - lbSXrefs->ScrollWidth = maxwid + 2; - lbSXrefs->ItemIndex = selIdx; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::pmStringsPopup(TObject *Sender) { - if (lbStrings->ItemIndex < 0) - return; -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Tab CXrefs -// *************************************************************************** -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::ShowCodeXrefs(DWORD Adr, int selIdx) { - lbCXrefs->Clear(); - PInfoRec recN = GetInfoRec(Adr); - if (recN && recN->xrefs) { - int wid, maxwid = 0; - TCanvas *canvas = lbCXrefs->Canvas; - DWORD pAdr = 0; - char f = 2; - - lbCXrefs->Items->BeginUpdate(); - - for (int m = 0; m < recN->xrefs->Count; m++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; - String line = " " + Val2Str8(recX->adr + recX->offset) + " " + recX->type; - wid = canvas->TextWidth(line); - if (wid > maxwid) - maxwid = wid; - PUnitRec recU = GetUnit(recX->adr); - if (recU && recU->kb) - line[1] ^= 1; - if (pAdr != recX->adr) - f ^= 2; - line[1] ^= f; - pAdr = recX->adr; - lbCXrefs->Items->Add(line); - } - lbCXrefs->ScrollWidth = maxwid + 2; - lbCXrefs->ItemIndex = selIdx; - lbCXrefs->ItemHeight = lbCXrefs->Canvas->TextHeight("T"); - lbCXrefs->Items->EndUpdate(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbXrefsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { - TListBox *lb = (TListBox*)Sender; - if (lb->CanFocus()) - ActiveControl = lb; -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbXrefsDblClick(TObject *Sender) { - char type[2]; - DWORD adr; - PROCHISTORYREC rec; - - TListBox *lb = (TListBox*)Sender; - if (lb->ItemIndex < 0) - return; - - String item = lb->Items->Strings[lb->ItemIndex]; - sscanf(AnsiString(item).c_str() + 1, "%lX%2c", &adr, type); - - if (type[1] == 'D') { - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->kind == ikVMT) { - ShowClassViewer(adr); - WhereSearch = SEARCH_CLASSVIEWER; - - if (!rgViewerMode->ItemIndex) { - TreeSearchFrom = tvClassesFull->Items->Item[0]; - } - else { - BranchSearchFrom = tvClassesShort->Items->Item[0]; - } - // Ñíà÷àëà èùåì êëàññ - String text = "#" + Val2Str8(adr); - FindText(text); - // Ãîòîì - òåêóùóþ ïðîöåäóðó - if (!rgViewerMode->ItemIndex) { - if (tvClassesFull->Selected) - TreeSearchFrom = tvClassesFull->Selected; - else - TreeSearchFrom = tvClassesFull->Items->Item[0]; - } - else { - if (tvClassesShort->Selected) - BranchSearchFrom = tvClassesShort->Selected; - else - BranchSearchFrom = tvClassesShort->Items->Item[0]; - } - text = "#" + Val2Str8(CurProcAdr); - FindText(text); - return; - } - } - - for (int m = Adr2Pos(adr); m >= 0; m--) { - if (IsFlagSet(cfProcStart, m)) { - rec.adr = CurProcAdr; - rec.itemIdx = lbCode->ItemIndex; - rec.xrefIdx = lbCXrefs->ItemIndex; - rec.topIdx = lbCode->TopIndex; - ShowCode(Pos2Adr(m), adr, -1, -1); - CodeHistoryPush(&rec); - break; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbXrefsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_RETURN) - lbXrefsDblClick(Sender); -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::lbXrefsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) { - int flags; - TColor _color; - TListBox *lb; - TCanvas *canvas; - String text, str; - - lb = (TListBox*)Control; - canvas = lb->Canvas; - SaveCanvas(canvas); - - if (Index < lb->Count) { - flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); - if (!Control->UseRightToLeftAlignment()) - Rect.Left += 2; - else - Rect.Right -= 2; - - text = lb->Items->Strings[Index]; - // lb->ItemHeight = canvas->TextHeight(text); - str = text.SubString(2, text.Length() - 1); - - if (text[1] & 2) { - if (!State.Contains(odSelected)) - canvas->Brush->Color = TColor(0xE7E7E7); - else - canvas->Brush->Color = TColor(0xFF0000); - } - canvas->FillRect(Rect); - - // Xrefs to Kb units - if (text[1] & 1) { - if (!State.Contains(odSelected)) - _color = TColor(0xC08000); // Blue - else - _color = TColor(0xBBBBBB); // LightGray - } - // Others - else { - if (!State.Contains(odSelected)) - _color = TColor(0x00B000); // Green - else - _color = TColor(0xBBBBBB); // LightGray - } - Rect.Right = Rect.Left; - DrawOneItem(str, canvas, Rect, _color, flags); - } - RestoreCanvas(canvas); -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Analyze1 -// *************************************************************************** -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// Create XRefs -// Scan procedure calls (include constructors and destructors) -// Calculate size of stack for arguments -void __fastcall TFMain_11011981::AnalyzeProc1(DWORD fromAdr, char xrefType, DWORD xrefAdr, int xrefOfs, bool maybeEmb) { - BYTE op, b1, b2; - bool bpBased = false; - WORD bpBase = 4; - int num, skipNum, instrLen, instrLen1, instrLen2, procSize; - DWORD b; - int fromPos, curPos, Pos, Pos1, Pos2; - DWORD curAdr, Adr, Adr1, finallyAdr, endAdr, maxAdr; - DWORD lastMovTarget = 0, lastCmpPos = 0, lastAdr = 0; - PInfoRec recN, recN1; - PXrefRec recX; - DISINFO DisInfo; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return; - - if (IsFlagSet(cfEmbedded, fromPos)) - return; - - recN = GetInfoRec(fromAdr); - - // Virtual constructor - don't analyze - if (recN && recN->type.Pos("class of ") == 1) - return; - - if (!recN) { - recN = new InfoRec(fromPos, ikRefine); - } - else if (recN->kind == ikUnknown || recN->kind == ikData) { - recN->kind = ikRefine; - recN->procInfo = new InfoProcInfo; - } - - // If xrefAdr != 0, add it to recN->xrefs - if (xrefAdr) { - recN->AddXref(xrefType, xrefAdr, xrefOfs); - SetFlag(cfProcStart, Adr2Pos(xrefAdr)); - } - - // Don't analyze imports - if (IsFlagSet(cfImport, fromPos)) - return; - // if (IsFlagSet(cfExport, fromPos)) return; - - // If Pass1 was set skip analyze - if (IsFlagSet(cfPass1, fromPos)) - return; - - if (!IsFlagSet(cfPass0, fromPos)) - AnalyzeProcInitial(fromAdr); - SetFlag(cfProcStart | cfPass1, fromPos); - - if (maybeEmb && !(recN->procInfo->flags & PF_EMBED)) - recN->procInfo->flags |= PF_MAYBEEMBED; - procSize = GetProcSize(fromAdr); - curPos = fromPos; - curAdr = fromAdr; - - while (1) { - if (curAdr >= CodeBase + TotalSize) - break; - // ---------------------------------- Try - // xor reg, reg cfTry | cfSkip - // push ebp cfSkip - // push offset @1 cfSkip - // push fs:[reg] cfSkip - // mov fs:[reg], esp cfSkip - // - // ---------------------------------- OnFinally - // xor reg, reg cfFinally | cfSkip - // pop reg cfSkip - // pop reg cfSkip - // pop reg cfSkip - // mov fs:[reg], esp cfSkip - // Adr1-1: push offset @3 cfSkip - // @2: ... - // ret cfSkip - // ---------------------------------- Finally - // @1: jmp @HandleFinally cfFinally | cfSkip - // jmp @2 cfFinally | cfSkip - // @3: ... end of Finally Section - // ---------------------------------- Except - // xor reg, reg cfExcept | cfSkip - // pop reg cfSkip - // pop reg cfSkip - // pop reg cfSkip - // mov fs:[reg], esp cfSkip - // jmp @3 -> End of Exception Section cfSkip - // @1: jmp @HandleAnyException cfExcept | cfSkip - // ... - // call DoneExcept - // ... - // @3: ... - // ---------------------------------- Except (another variant, rear) - // pop fs:[0] cfExcept | cfSkip - // add esp,8 cfSkip - // jmp @3 -> End of Exception Section cfSkip - // @1: jmp @HandleAnyException cfExcept | cfSkip - // ... - // call DoneExcept - // ... - // @3: ... - // ---------------------------------- OnExcept - // xor reg, reg cfExcept | cfSkip - // pop reg cfSkip - // pop reg cfSkip - // pop reg cfSkip - // mov fs:[reg], esp cfSkip - // jmp @3 -> End of Exception Section cfSkip - // @1: jmp HandleOnException cfExcept | cfSkip - // dd num cfETable - // Table from num records: - // dd offset ExceptionInfo - // dd offset ExceptionProc - // ... - // @3: ... - // ---------------------------------- - // Is it try section begin (skipNum > 0)? - skipNum = IsTryBegin(curAdr, &finallyAdr) + IsTryBegin0(curAdr, &finallyAdr); - if (skipNum > 0) { - Adr = finallyAdr; // Adr=@1 - Pos = Adr2Pos(Adr); - if (Pos < 0) - break; - if (Adr > lastAdr) - lastAdr = Adr; - SetFlag(cfTry, curPos); - SetFlags(cfSkip, curPos, skipNum); - - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN1 = GetInfoRec(DisInfo.Immediate); - if (recN1 && recN1->HasName()) { - // jmp @HandleFinally - if (recN1->SameName("@HandleFinally")) { - SetFlag(cfFinally, Pos); // @1 - SetFlags(cfSkip, Pos - 1, instrLen1 + 1); // ret + jmp HandleFinally - - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Pos2Adr(Pos), &DisInfo, 0); - SetFlag(cfFinally, Pos); // jmp @2 - SetFlags(cfSkip, Pos, instrLen2); // jmp @2 - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - - Pos = Adr2Pos(DisInfo.Immediate); // @2 - // Get prev (before Pos) instruction - Pos1 = GetNearestUpInstruction(Pos); - instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); - // If push XXXXXXXX -> set new lastAdr - if (Disasm.GetOp(DisInfo.Mnem) == OP_PUSH) { - SetFlags(cfSkip, Pos1, instrLen2); - if (DisInfo.OpType[0] == otIMM && DisInfo.Immediate > lastAdr) - lastAdr = DisInfo.Immediate; - } - - // Find nearest up instruction with segment prefix fs: - Pos1 = GetNearestUpPrefixFs(Pos); - instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); - // pop fs:[0] - if (Disasm.GetOp(DisInfo.Mnem) == OP_POP) { - SetFlags(cfSkip, Pos1, Pos - Pos1); - } - // mov fs:[0],reg - else if (DisInfo.OpType[0] == otMEM && DisInfo.BaseReg == -1 && DisInfo.Offset == 0) { - Pos2 = GetNthUpInstruction(Pos1, 3); - SetFlag(cfFinally, Pos2); - SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); - } - // mov fs:[reg1], reg2 - else { - Pos2 = GetNthUpInstruction(Pos1, 4); - SetFlag(cfFinally, Pos2); - SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); - } - } - else if (recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleAutoException")) { - SetFlag(cfExcept, Pos); // @1 - // Find nearest up instruction with segment prefix fs: - Pos1 = GetNearestUpPrefixFs(Pos); - instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); - // pop fs:[0] - if (Disasm.GetOp(DisInfo.Mnem) == OP_POP) { - SetFlags(cfSkip, Pos1, Pos - Pos1); - } - // mov fs:[0],reg - else if (DisInfo.OpType[0] == otMEM && DisInfo.BaseReg == -1 && DisInfo.Offset == 0) { - Pos2 = GetNthUpInstruction(Pos1, 3); - SetFlag(cfExcept, Pos2); - SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); - } - // mov fs:[reg1], reg2 - else { - Pos2 = GetNthUpInstruction(Pos1, 4); - SetFlag(cfExcept, Pos2); - SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); - } - - // Get prev (before Pos) instruction - Pos1 = GetNearestUpInstruction(Pos); - Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); - // If jmp -> set new lastAdr - if (Disasm.GetOp(DisInfo.Mnem) == OP_JMP && DisInfo.Immediate > lastAdr) - lastAdr = DisInfo.Immediate; - } - else if (recN1->SameName("@HandleOnException")) { - SetFlag(cfExcept, Pos); // @1 - // Find nearest up instruction with segment prefix fs: - Pos1 = GetNearestUpPrefixFs(Pos); - instrLen2 = Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); - // pop fs:[0] - if (Disasm.GetOp(DisInfo.Mnem) == OP_POP) { - SetFlags(cfSkip, Pos1, Pos - Pos1); - } - // mov fs:[0],reg - else if (DisInfo.OpType[0] == otMEM && DisInfo.BaseReg == -1 && DisInfo.Offset == 0) { - Pos2 = GetNthUpInstruction(Pos1, 3); - SetFlag(cfExcept, Pos2); - SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); - } - // mov fs:[reg1], reg2 - else { - Pos2 = GetNthUpInstruction(Pos1, 4); - SetFlag(cfExcept, Pos2); - SetFlags(cfSkip, Pos2, Pos1 - Pos2 + instrLen2); - } - - // Get prev (before Pos) instruction - Pos1 = GetNearestUpInstruction(Pos); - Disasm.Disassemble(Pos2Adr(Pos1), &DisInfo, 0); - // If jmp -> set new lastAdr - if (Disasm.GetOp(DisInfo.Mnem) == OP_JMP && DisInfo.Immediate > lastAdr) - lastAdr = DisInfo.Immediate; - - // Next instruction - Pos += instrLen1; - Adr += instrLen1; - // Set flag cfETable - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - SetFlags(cfSkip, Pos, 4); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - SetFlags(cfSkip, Pos, 4); - Pos += 4; - // dd offset ExceptionProc - DWORD procAdr = *((DWORD*)(Code + Pos)); - if (IsValidCodeAdr(procAdr)) - SetFlag(cfLoc, Adr2Pos(procAdr)); - SetFlags(cfSkip, Pos, 4); - Pos += 4; - } - } - } - curPos += skipNum; - curAdr += skipNum; - continue; - } - // Is it finally section? - skipNum = IsTryEndPush(curAdr, &endAdr); - if (skipNum > 0) { - SetFlag(cfFinally, curPos); - SetFlags(cfSkip, curPos, skipNum); - if (endAdr > lastAdr) - lastAdr = endAdr; - curPos += skipNum; - curAdr += skipNum; - continue; - } - // Finally section in if...then...else constructions - skipNum = IsTryEndJump(curAdr, &endAdr); - if (skipNum > 0) { - SetFlag(cfFinally | cfExcept, curPos); - SetFlags(cfSkip, curPos, skipNum); - if (endAdr > lastAdr) - lastAdr = endAdr; - curPos += skipNum; - curAdr += skipNum; - continue; - } - // Int64NotEquality - // skipNum = ProcessInt64NotEquality(curAdr, &maxAdr); - // if (skipNum > 0) - // { - // if (maxAdr > lastAdr) lastAdr = maxAdr; - // curPos += skipNum; curAdr += skipNum; - // continue; - // } - // Int64Equality - // skipNum = ProcessInt64Equality(curAdr, &maxAdr); - // if (skipNum > 0) - // { - // if (maxAdr > lastAdr) lastAdr = maxAdr; - // curPos += skipNum; curAdr += skipNum; - // continue; - // } - // Int64Comparison - skipNum = ProcessInt64Comparison(curAdr, &maxAdr); - if (skipNum > 0) { - if (maxAdr > lastAdr) - lastAdr = maxAdr; - curPos += skipNum; - curAdr += skipNum; - continue; - } - // Int64ComparisonViaStack1 - skipNum = ProcessInt64ComparisonViaStack1(curAdr, &maxAdr); - if (skipNum > 0) { - if (maxAdr > lastAdr) - lastAdr = maxAdr; - curPos += skipNum; - curAdr += skipNum; - continue; - } - // Int64ComparisonViaStack2 - skipNum = ProcessInt64ComparisonViaStack2(curAdr, &maxAdr); - if (skipNum > 0) { - if (maxAdr > lastAdr) - lastAdr = maxAdr; - curPos += skipNum; - curAdr += skipNum; - continue; - } - // Skip exception table - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - curPos += 4 + 8 * num; - curAdr += 4 + 8 * num; - continue; - } - b1 = Code[curPos]; - b2 = Code[curPos + 1]; - if (!b1 && !b2 && !lastAdr) - break; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) break; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - op = Disasm.GetOp(DisInfo.Mnem); - // Code - SetFlags(cfCode, curPos, instrLen); - // Instruction begin - SetFlag(cfInstruction, curPos); - - if (curAdr >= lastAdr) - lastAdr = 0; - - // Frame instructions - if (curAdr == fromAdr && b1 == 0x55) // push ebp - { - SetFlag(cfFrame, curPos); - } - if (b1 == 0x8B && b2 == 0xEC) // mov ebp, esp - { - bpBased = true; - recN->procInfo->flags |= PF_BPBASED; - recN->procInfo->bpBase = bpBase; - - SetFlags(cfFrame, curPos, instrLen); - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (b1 == 0x8B && b2 == 0xE5) // mov esp, ebp - { - SetFlags(cfFrame, curPos, instrLen); - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (op == OP_JMP) { - if (curAdr == fromAdr) - break; - if (DisInfo.OpType[0] == otMEM) { - if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) - break; - } - if (DisInfo.OpType[0] == otIMM) { - Adr = DisInfo.Immediate; - Pos = Adr2Pos(Adr); - if (Pos < 0 && (!lastAdr || curAdr == lastAdr)) - break; - if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) - break; - SetFlag(cfLoc, Pos); - recN1 = GetInfoRec(Adr); - if (!recN1) - recN1 = new InfoRec(Pos, ikUnknown); - recN1->AddXref('J', fromAdr, curAdr - fromAdr); - - if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) - break; - } - } - - // End of procedure - if (DisInfo.Ret) { - if (!lastAdr || curAdr == lastAdr) { - // Proc end - // SetFlag(cfProcEnd, curPos + instrLen - 1); - recN->procInfo->procSize = curAdr - fromAdr + instrLen; - recN->procInfo->retBytes = 0; - // ret N - if (DisInfo.OpNum) { - recN->procInfo->retBytes = DisInfo.Immediate; // num; - } - break; - } - } - // push - if (op == OP_PUSH) { - SetFlag(cfPush, curPos); - bpBase += 4; - } - // pop - if (op == OP_POP) - SetFlag(cfPop, curPos); - // add (sub) esp,... - if (DisInfo.OpRegIdx[0] == 20 && DisInfo.OpType[1] == otIMM) { - if (op == OP_ADD) - bpBase -= (int)DisInfo.Immediate; - if (op == OP_SUB) - bpBase += (int)DisInfo.Immediate; - // skip - SetFlags(cfSkip, curPos, instrLen); - curPos += instrLen; - curAdr += instrLen; - continue; - } - ////fstp [esp] - // if (!memcmp(DisInfo.Mnem, "fst", 3) && DisInfo.BaseReg == 20) SetFlag(cfFush, curPos); - - // skip - if (!memcmp(DisInfo.Mnem, "sahf", 4) || !memcmp(DisInfo.Mnem, "wait", 4)) { - SetFlags(cfSkip, curPos, instrLen); - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (op == OP_MOV) - lastMovTarget = DisInfo.Offset; - if (op == OP_CMP) - lastCmpPos = curPos; - - // Is instruction (not call and jmp), that contaibs operand [reg+xxx], where xxx is negative value - if (maybeEmb && !DisInfo.Call && !DisInfo.Branch && (int)DisInfo.Offset < - 0 && (DisInfo.IndxReg == -1 && (DisInfo.BaseReg >= 16 && DisInfo.BaseReg <= 23 && DisInfo.BaseReg != 20 && DisInfo.BaseReg != 21))) { - // May be add condition that all Xrefs must points to one subroutine!!!!!!!!!!!!! - if ((bpBased && DisInfo.BaseReg != 21) || (!bpBased && DisInfo.BaseReg != 20)) { - recN->procInfo->flags |= PF_EMBED; - } - } - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) // near absolute indirect jmp (Case) - { - if (!IsValidCodeAdr(DisInfo.Offset)) { - // SetFlag(cfProcEnd, curPos + instrLen - 1); - recN->procInfo->procSize = curAdr - fromAdr + instrLen; - break; - } - DWORD cTblAdr = 0, jTblAdr = 0; - SetFlag(cfSwitch, lastCmpPos); - SetFlag(cfSwitch, curPos); - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Table address - last 4 bytes of instruction - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Scan gap to find table cTbl - if (Adr <= lastMovTarget && lastMovTarget < jTblAdr) - cTblAdr = lastMovTarget; - // If exists cTblAdr, skip it - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - SetFlags(cfSkip, Pos, CNum); - Pos += CNum; - Adr += CNum; - } - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - SetFlags(cfSkip, Pos, 4); - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // Check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0 && Pos - NPos < MAX_DISASSEMBLE) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - if (Code[NPos + 2] == 0x35) { - SetFlag(cfTry, NPos - 6); - SetFlags(cfSkip, NPos - 6, 20); - } - else { - SetFlag(cfTry, NPos - 8); - SetFlags(cfSkip, NPos - 8, 14); - } - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN1 = GetInfoRec(DisInfo.Immediate); - if (recN1 && recN1->HasName()) { - // jmp @HandleFinally - if (recN1->SameName("@HandleFinally")) { - SetFlag(cfFinally, Pos); - - SetFlags(cfSkip, Pos - 1, instrLen1 + 1); // ret + jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - SetFlag(cfFinally, Pos); - SetFlags(cfSkip, Pos, instrLen2); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - // int hfEndPos = Adr2Pos(Adr); - - int hfStartPos = Adr2Pos(DisInfo.Immediate); - assert(hfStartPos >= 0); - - Pos = hfStartPos - 5; - - if (Code[Pos] == 0x68) // push offset @3 //Flags[Pos] & cfInstruction must be != 0 - { - hfStartPos = Pos - 8; - SetFlags(cfSkip, hfStartPos, 13); - } - SetFlag(cfFinally, hfStartPos); - } - else if (recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleAutoException")) { - SetFlag(cfExcept, Pos); - - int hoStartPos = Pos - 10; - SetFlags(cfSkip, hoStartPos, instrLen1 + 10); - Disasm.Disassemble(Code + Pos - 10, (__int64)(Adr - 10), &DisInfo, 0); - if (Disasm.GetOp(DisInfo.Mnem) != OP_XOR || DisInfo.OpRegIdx[0] != DisInfo.OpRegIdx[1]) { - hoStartPos = Pos - 13; - SetFlags(cfSkip, hoStartPos, instrLen1 + 13); - } - // Find prev jmp - Pos1 = hoStartPos; - Adr1 = Pos2Adr(Pos1); - for (int k = 0; k < 6; k++) { - instrLen2 = Disasm.Disassemble(Code + Pos1, (__int64)Adr1, &DisInfo, 0); - Pos1 += instrLen2; - Adr1 += instrLen2; - } - if (DisInfo.Immediate > lastAdr) - lastAdr = DisInfo.Immediate; - // int hoEndPos = Adr2Pos(DisInfo.Immediate); - - SetFlag(cfExcept, hoStartPos); - } - else if (recN1->SameName("@HandleOnException")) { - SetFlag(cfExcept, Pos); - - int hoStartPos = Pos - 10; - SetFlags(cfSkip, hoStartPos, instrLen1 + 10); - Disasm.Disassemble(Code + Pos - 10, (__int64)(Adr - 10), &DisInfo, 0); - if (Disasm.GetOp(DisInfo.Mnem) != OP_XOR || DisInfo.OpRegIdx[0] != DisInfo.OpRegIdx[1]) { - hoStartPos = Pos - 13; - SetFlags(cfSkip, hoStartPos, instrLen1 + 13); - } - // Find prev jmp - Pos1 = hoStartPos; - Adr1 = Pos2Adr(Pos1); - for (int k = 0; k < 6; k++) { - instrLen2 = Disasm.Disassemble(Code + Pos1, (__int64)Adr1, &DisInfo, 0); - Pos1 += instrLen2; - Adr1 += instrLen2; - } - if (DisInfo.Immediate > lastAdr) - lastAdr = DisInfo.Immediate; - // int hoEndPos = Adr2Pos(DisInfo.Immediate); - - SetFlag(cfExcept, hoStartPos); - - // Next instruction - Pos += instrLen1; - Adr += instrLen1; - // Set flag cfETable - SetFlag(cfETable, Pos); - // dd num - num = *((int*)(Code + Pos)); - SetFlags(cfSkip, Pos, 4); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - SetFlags(cfSkip, Pos, 4); - Pos += 4; - // dd offset ExceptionProc - DWORD procAdr = *((DWORD*)(Code + Pos)); - if (IsValidCodeAdr(procAdr)) - SetFlag(cfLoc, Adr2Pos(procAdr)); - SetFlags(cfSkip, Pos, 4); - Pos += 4; - } - } - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - if (DisInfo.Call) { - SetFlag(cfCall, curPos); - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr) && Adr2Pos(Adr) >= 0) { - SetFlag(cfLoc, Adr2Pos(Adr)); - // If after call exists instruction pop ecx, it may be embedded procedure - bool mbemb = (Code[curPos + instrLen] == 0x59); - AnalyzeProc1(Adr, 'C', fromAdr, curAdr - fromAdr, mbemb); - - recN1 = GetInfoRec(Adr); - if (recN1 && recN1->procInfo) { - // After embedded proc instruction pop ecx must be skipped - if (mbemb && recN1->procInfo->flags & PF_EMBED) - SetFlag(cfSkip, curPos + instrLen); - - if (recN1->HasName()) { - if (recN1->SameName("@Halt0")) { - SetFlags(cfSkip, curPos, instrLen); - if (fromAdr == EP && !lastAdr) { - // SetFlag(cfProcEnd, curPos + instrLen - 1); - recN->procInfo->procSize = curAdr - fromAdr + instrLen; - recN->SetName("EntryPoint"); - recN->procInfo->retBytes = 0; - break; - } - } - - int begPos, endPos; - // If called procedure is @ClassCreate, then current procedure is constructor - if (recN1->SameName("@ClassCreate")) { - recN->kind = ikConstructor; - // Code from instruction test... until this call is not sufficient (mark skipped) - begPos = GetNearestUpInstruction1(curPos, fromPos, "test"); - if (begPos != -1) - SetFlags(cfSkip, begPos, curPos + instrLen - begPos); - } - else if (recN1->SameName("@AfterConstruction")) { - begPos = GetNearestUpInstruction2(curPos, fromPos, "test", "cmp"); - endPos = GetNearestDownInstruction(curPos, "add"); - if (begPos != -1 && endPos != -1) - SetFlags(cfSkip, begPos, endPos - begPos); - } - else if (recN1->SameName("@BeforeDestruction")) - SetFlag(cfSkip, curPos); - // If called procedure is @ClassDestroy, then current procedure is destructor - else if (recN1->SameName("@ClassDestroy")) { - recN->kind = ikDestructor; - begPos = GetNearestUpInstruction2(curPos, fromPos, "test", "cmp"); - if (begPos != -1) - SetFlags(cfSkip, begPos, curPos + instrLen - begPos); - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (b1 == 0xEB || // short relative abs jmp or cond jmp - (b1 >= 0x70 && b1 <= 0x7F) || (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - Pos = Adr2Pos(Adr); - if (!IsFlagSet(cfEmbedded, Pos)) // Possible branch to start of Embedded proc (for ex. in proc TextToFloat)) - { - SetFlag(cfLoc, Pos); - // Mark possible start of Loop - if (Adr < curAdr && !IsFlagSet(cfFinally, Adr2Pos(curAdr)) && !IsFlagSet(cfExcept, Adr2Pos(curAdr))) - SetFlag(cfLoop, Pos); - recN1 = GetInfoRec(Adr); - if (!recN1) - recN1 = new InfoRec(Pos, ikUnknown); - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (b1 == 0xE9) // relative abs jmp or cond jmp - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - Pos = Adr2Pos(Adr); - SetFlag(cfLoc, Pos); - // Mark possible start of Loop - if (Adr < curAdr && !IsFlagSet(cfFinally, Adr2Pos(curAdr)) && !IsFlagSet(cfExcept, Adr2Pos(curAdr))) - SetFlag(cfLoop, Pos); - recN1 = GetInfoRec(Adr); - if (recN1 && recN1->HasName()) { - if (recN1->SameName("@HandleFinally") || recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleOnException") || recN1->SameName("@HandleAutoException")) { - recN1->AddXref('J', fromAdr, curAdr - fromAdr); - } - } - if (!recN1 && Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - // Second operand - immediate and is valid address - if (DisInfo.OpType[1] == otIMM) { - Pos = Adr2Pos(DisInfo.Immediate); - // imm32 must be valid code address outside current procedure - if (Pos >= 0 && IsValidCodeAdr(DisInfo.Immediate) && (DisInfo.Immediate < fromAdr || DisInfo.Immediate >= fromAdr + procSize)) { - // Position must be free - if (!Flags[Pos]) { - // No Name - if (!Infos[Pos]) { - // Address must be outside current procedure - if (DisInfo.Immediate < fromAdr || DisInfo.Immediate >= fromAdr + procSize) { - // If valid code lets user decide later - int codeValidity = IsValidCode(DisInfo.Immediate); - - if (codeValidity == 1) // Code - AnalyzeProc1(DisInfo.Immediate, 'D', fromAdr, curAdr - fromAdr, false); - } - } - } - // If slot is not free (procedure is already loaded) - else if (IsFlagSet(cfProcStart, Pos)) - AnalyzeProc1(DisInfo.Immediate, 'D', fromAdr, curAdr - fromAdr, false); - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - curPos += instrLen; - curAdr += instrLen; - } -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// Analyze2 -// *************************************************************************** -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -void __fastcall AddFieldXref(PFIELDINFO fInfo, DWORD ProcAdr, int ProcOfs, char type); -// --------------------------------------------------------------------------- -// structure for saving context of all registers (branch instruction) -typedef struct { - int sp; - DWORD adr; - RINFO registers[32]; -} RCONTEXT, *PRCONTEXT; - -// --------------------------------------------------------------------------- -PRCONTEXT __fastcall GetCtx(TList* Ctx, DWORD Adr) { - for (int n = 0; n < Ctx->Count; n++) { - PRCONTEXT rinfo = (PRCONTEXT)Ctx->Items[n]; - if (rinfo->adr == Adr) - return rinfo; - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall SetRegisterValue(PRINFO regs, int Idx, DWORD Value) { - if (Idx >= 16 && Idx <= 19) { - regs[Idx - 16].value = Value; - regs[Idx - 12].value = Value; - regs[Idx - 8].value = Value; - regs[Idx].value = Value; - return; - } - if (Idx >= 20 && Idx <= 23) { - regs[Idx - 8].value = Value; - regs[Idx].value = Value; - return; - } - if (Idx >= 0 && Idx <= 3) { - regs[Idx].value = Value; - regs[Idx + 8].value = Value; - regs[Idx + 16].value = Value; - return; - } - if (Idx >= 4 && Idx <= 7) { - regs[Idx].value = Value; - regs[Idx + 4].value = Value; - regs[Idx + 12].value = Value; - return; - } - if (Idx >= 8 && Idx <= 11) { - regs[Idx - 8].value = Value; - regs[Idx - 4].value = Value; - regs[Idx].value = Value; - regs[Idx + 8].value = Value; - return; - } - if (Idx >= 12 && Idx <= 15) { - regs[Idx].value = Value; - regs[Idx + 8].value = Value; - return; - } -} - -// --------------------------------------------------------------------------- -// Possible values -// 'V' - Virtual table base (for calls processing) -// 'v' - var -// 'L' - lea local var -// 'l' - local var -// 'A' - lea argument -// 'a' - argument -// 'I' - Integer -void __fastcall SetRegisterSource(PRINFO regs, int Idx, char Value) { - if (Idx >= 16 && Idx <= 19) { - regs[Idx - 16].source = Value; - regs[Idx - 12].source = Value; - regs[Idx - 8].source = Value; - regs[Idx].source = Value; - return; - } - if (Idx >= 20 && Idx <= 23) { - regs[Idx - 8].source = Value; - regs[Idx].source = Value; - return; - } - if (Idx >= 0 && Idx <= 3) { - regs[Idx].source = Value; - regs[Idx + 8].source = Value; - regs[Idx + 16].source = Value; - return; - } - if (Idx >= 4 && Idx <= 7) { - regs[Idx].source = Value; - regs[Idx + 4].source = Value; - regs[Idx + 12].source = Value; - return; - } - if (Idx >= 8 && Idx <= 11) { - regs[Idx - 8].source = Value; - regs[Idx - 4].source = Value; - regs[Idx].source = Value; - regs[Idx + 8].source = Value; - return; - } - if (Idx >= 12 && Idx <= 15) { - regs[Idx].source = Value; - regs[Idx + 8].source = Value; - return; - } -} - -// --------------------------------------------------------------------------- -void __fastcall SetRegisterType(PRINFO regs, int Idx, String Value) { - if (Idx >= 16 && Idx <= 19) { - regs[Idx - 16].type = Value; - regs[Idx - 12].type = Value; - regs[Idx - 8].type = Value; - regs[Idx].type = Value; - return; - } - if (Idx >= 20 && Idx <= 23) { - regs[Idx - 8].type = Value; - regs[Idx].type = Value; - return; - } - if (Idx >= 0 && Idx <= 3) { - regs[Idx].type = Value; - regs[Idx + 8].type = Value; - regs[Idx + 16].type = Value; - return; - } - if (Idx >= 4 && Idx <= 7) { - regs[Idx].type = Value; - regs[Idx + 4].type = Value; - regs[Idx + 12].type = Value; - return; - } - if (Idx >= 8 && Idx <= 11) { - regs[Idx - 8].type = Value; - regs[Idx - 4].type = Value; - regs[Idx].type = Value; - regs[Idx + 8].type = Value; - return; - } - if (Idx >= 12 && Idx <= 15) { - regs[Idx].type = Value; - regs[Idx + 8].type = Value; - return; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFMain_11011981::AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType) { - // saved context - TList *sctx = new TList; - for (int n = 0; n < 3; n++) { - if (!AnalyzeProc2(fromAdr, addArg, AnalyzeRetType, sctx)) - break; - } - // delete sctx - CleanupList(sctx); -} - -// --------------------------------------------------------------------------- -bool __fastcall TFMain_11011981::AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType, TList *sctx) { - BYTE op, b1, b2; - char source; - bool reset, bpBased, vmt, fContinue = false; - WORD bpBase; - int n, num, instrLen, instrLen1, instrLen2, _ap, _procSize; - int reg1Idx, reg2Idx; - int sp = -1, fromIdx = -1; // fromIdx - index of register in instruction mov eax,reg (for processing call @IsClass) - DWORD b; - int fromPos, curPos, Pos; - DWORD curAdr; - DWORD lastMovAdr = 0; - DWORD procAdr, Val, Adr, Adr1; - DWORD reg, varAdr, classAdr, vmtAdr, lastAdr = 0; - PInfoRec recN, recN1; - PLOCALINFO locInfo; - PARGINFO argInfo; - PFIELDINFO fInfo = 0; - PRCONTEXT rinfo; - RINFO rtmp; - String comment, typeName, className = "", varName, varType; - String _eax_Type, _edx_Type, _ecx_Type, sType; - RINFO registers[32]; - RINFO stack[256]; - DISINFO DisInfo, DisInfo1; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return false; - if (IsFlagSet(cfPass2, fromPos)) - return false; - if (IsFlagSet(cfEmbedded, fromPos)) - return false; - if (IsFlagSet(cfExport, fromPos)) - return false; - - // b1 = Code[fromPos]; - // b2 = Code[fromPos + 1]; - // if (!b1 && !b2) return false; - - // Import - return ret type of function - if (IsFlagSet(cfImport, fromPos)) - return false; - recN = GetInfoRec(fromAdr); - - // if recN = 0 (Interface Methods!!!) then return - if (!recN || !recN->procInfo) - return false; - - // Procedure from Knowledge Base not analyzed - if (recN && recN->kbIdx != -1) - return false; - - // if (!IsFlagSet(cfPass1, fromPos)) - // ??? - - SetFlag(cfProcStart | cfPass2, fromPos); - - // If function name contains class name get it - className = ExtractClassName(recN->GetName()); - bpBased = (recN->procInfo->flags & PF_BPBASED); - bpBase = (recN->procInfo->bpBase); - - rtmp.result = 0; - rtmp.source = 0; - rtmp.value = 0; - rtmp.type = ""; - for (n = 0; n < 32; n++) - registers[n] = rtmp; - - // Get args - _eax_Type = _edx_Type = _ecx_Type = ""; - BYTE callKind = recN->procInfo->flags & 7; - if (recN->procInfo->args && !callKind) { - for (n = 0; n < recN->procInfo->args->Count; n++) { - PARGINFO argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - if (argInfo->Ndx == 0) { - if (className != "") - registers[16].type = className; - else - registers[16].type = argInfo->TypeDef; - _eax_Type = registers[16].type; - // var - if (argInfo->Tag == 0x22) - registers[16].source = 'v'; - continue; - } - if (argInfo->Ndx == 1) { - registers[18].type = argInfo->TypeDef; - _edx_Type = registers[18].type; - // var - if (argInfo->Tag == 0x22) - registers[18].source = 'v'; - continue; - } - if (argInfo->Ndx == 2) { - registers[17].type = argInfo->TypeDef; - _ecx_Type = registers[17].type; - // var - if (argInfo->Tag == 0x22) - registers[17].source = 'v'; - continue; - } - break; - } - } - else if (className != "") { - registers[16].type = className; - } - - _procSize = GetProcSize(fromAdr); - curPos = fromPos; - curAdr = fromAdr; - - while (1) { - if (curAdr >= CodeBase + TotalSize) - break; - - // Skip exception table - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - curPos += 4 + 8 * num; - curAdr += 4 + 8 * num; - continue; - } - - b1 = Code[curPos]; - b2 = Code[curPos + 1]; - if (!b1 && !b2 && !lastAdr) - break; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) break; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - - op = Disasm.GetOp(DisInfo.Mnem); - // Code - SetFlags(cfCode, curPos, instrLen); - // Instruction begin - SetFlag(cfInstruction, curPos); - - if (curAdr >= lastAdr) - lastAdr = 0; - - if (op == OP_JMP) { - if (curAdr == fromAdr) - break; - if (DisInfo.OpType[0] == otMEM) { - if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) - break; - } - if (DisInfo.OpType[0] == otIMM) { - Adr = DisInfo.Immediate; - if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) - break; - if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) - break; - if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) - break; - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - if (DisInfo.Ret) { - // End of proc - if (!lastAdr || curAdr == lastAdr) { - if (AnalyzeRetType) { - // Åñëè òèï ðåãèñòðà eax íå ïóñòîé, íàõîäèì áëèæàéøóþ ñâåðõó èíñòðóêöèþ åãî èíöèàëèçàöèè - if (registers[16].type != "") { - for (Pos = curPos - 1; Pos >= fromPos; Pos--) { - b = Flags[Pos]; - if ((b & cfInstruction)&!(b & cfSkip)) { - Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo, 0); - // If branch - break - if (DisInfo.Branch) - break; - // If call - // Other cases (call [reg+Ofs]; call [Adr]) need to add - if (DisInfo.Call) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - recN1 = GetInfoRec(Adr); - if (recN1 && recN1->procInfo /* recN1->kind == ikFunc */) { - typeName = recN1->type; - recN1 = GetInfoRec(fromAdr); - if (!(recN1->procInfo->flags & (PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->kind = ikFunc; - recN1->type = typeName; - } - } - } - } - else if (b & cfSetA) { - recN1 = GetInfoRec(fromAdr); - if (!(recN1->procInfo->flags & (PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->kind = ikFunc; - recN1->type = registers[16].type; - } - } - } - } - } - } - break; - } - if (!IsFlagSet(cfSkip, curPos)) - sp = -1; - } - - // cfBracket - if (IsFlagSet(cfBracket, curPos)) { - if (op == OP_PUSH && sp < 255) { - reg1Idx = DisInfo.OpRegIdx[0]; - sp++; - stack[sp] = registers[reg1Idx]; - } - else if (op == OP_POP && sp >= 0) { - reg1Idx = DisInfo.OpRegIdx[0]; - registers[reg1Idx] = stack[sp]; - sp--; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - // Ãðîâåðèì, íå ïîïàë ëè âíóòðü èíñòðóêöèè Fixup èëè ThreadVar - bool NameInside = false; - for (int k = 1; k < instrLen; k++) { - if (Infos[curPos + k]) { - NameInside = true; - break; - } - } - - reset = ((op & OP_RESET) != 0); - - if (op == OP_MOV) - lastMovAdr = DisInfo.Offset; - - // If loc then try get context - if (curAdr != fromAdr && IsFlagSet(cfLoc, curPos)) { - rinfo = GetCtx(sctx, curAdr); - if (rinfo) { - sp = rinfo->sp; - for (n = 0; n < 32; n++) - registers[n] = rinfo->registers[n]; - } - // context not found - set flag to continue on the next step - else { - fContinue = true; - } - } - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) // near absolute indirect jmp (Case) - { - if (!IsValidCodeAdr(DisInfo.Offset)) - break; - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Àäðåñ òàáëèöû - ïîñëåäíèå 4 áàéòà èíñòðóêöèè - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Àíàëèçèðóåì ïðîìåæóòîê íà ïðåäìåò òàáëèöû cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // Åñëè åñòü cTblAdr, ïðîïóñêàåì ýòó òàáëèöó - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - Pos += CNum; - Adr += CNum; - } - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - // Save context - if (!GetCtx(sctx, Adr1)) { - rinfo = new RCONTEXT; - rinfo->sp = sp; - rinfo->adr = Adr1; - for (n = 0; n < 32; n++) - rinfo->registers[n] = registers[n]; - sctx->Add((void*)rinfo); - } - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0 && Pos - NPos < MAX_DISASSEMBLE) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN = GetInfoRec(DisInfo.Immediate); - if (recN) { - if (recN->SameName("@HandleFinally")) { - // jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleAnyException") || recN->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Adr = *((DWORD*)(Code + Pos)); - Pos += 4; - if (IsValidImageAdr(Adr)) { - recN1 = GetInfoRec(Adr); - if (recN1 && recN1->kind == ikVMT) - className = recN1->GetName(); - } - // dd offset ExceptionProc - procAdr = *((DWORD*)(Code + Pos)); - Pos += 4; - if (IsValidImageAdr(procAdr)) { - // Save context - if (!GetCtx(sctx, procAdr)) { - rinfo = new RCONTEXT; - rinfo->sp = sp; - rinfo->adr = procAdr; - for (n = 0; n < 32; n++) - rinfo->registers[n] = registers[n]; - // eax - rinfo->registers[16].value = GetClassAdr(className); - rinfo->registers[16].type = className; - - sctx->Add((void*)rinfo); - } - } - } - } - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - // branch - if (DisInfo.Branch) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - _ap = Adr2Pos(Adr); - // SetFlag(cfLoc, _ap); - // recN1 = GetInfoRec(Adr); - // if (!recN1) recN1 = new InfoRec(_ap, ikUnknown); - // recN1->AddXref('C', fromAdr, curAdr - fromAdr); - // Save context - if (!GetCtx(sctx, Adr)) { - rinfo = new RCONTEXT; - rinfo->sp = sp; - rinfo->adr = Adr; - for (n = 0; n < 32; n++) - rinfo->registers[n] = registers[n]; - sctx->Add((void*)rinfo); - } - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (registers[16].type != "" && registers[16].type[1] == '#') { - DWORD dd = *((DWORD*)(registers[16].type.c_str())); - // Åñëè áûë âûçîâ ôóíêöèè @GetTls, ñìîòðèì ñëåä. èíñòðóêöèþ âèäà [eax+N] - if (dd == 'SLT#') { - // Åñëè íåò âíóòðåííåãî èìåíè (Fixup, ThreadVar) - if (!NameInside) { - // Destination (GlobalLists := TList.Create) - // Source (GlobalLists.Add) - if ((DisInfo.OpType[0] == otMEM || DisInfo.OpType[1] == otMEM) && DisInfo.BaseReg == 16) { - _ap = Adr2Pos(curAdr); - assert(_ap >= 0); - recN1 = GetInfoRec(curAdr + 1); - if (!recN1) - recN1 = new InfoRec(_ap + 1, ikThreadVar); - if (!recN1->HasName()) - recN1->SetName(String("threadvar_") + DisInfo.Offset); - } - } - SetRegisterValue(registers, 16, 0xFFFFFFFF); - registers[16].type = ""; - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - // Call - if (DisInfo.Call) { - Adr = DisInfo.Immediate; - if (IsValidImageAdr(Adr)) { - recN = GetInfoRec(Adr); - if (recN && recN->procInfo) { - int retBytes = (int)recN->procInfo->retBytes; - if (retBytes != -1 && sp >= retBytes) - sp -= retBytes; - else - sp = -1; - - // for constructor type is in eax - if (recN->kind == ikConstructor) { - // Åñëè dl = 1, ðåãèñòð eax ïîñëå âûçîâà èñïîëüçóåòñÿ - if (registers[2].value == 1) { - classAdr = GetClassAdr(registers[16].type); - if (IsValidImageAdr(classAdr)) { - // Add xref to vmt info - recN1 = GetInfoRec(classAdr); - recN1->AddXref('D', Adr, 0); - - comment = registers[16].type + ".Create"; - AddPicode(curPos, OP_CALL, comment, 0); - AnalyzeTypes(fromAdr, curPos, Adr, registers); - } - } - SetFlag(cfSetA, curPos); - } - else { - // Found @Halt0 - exit - if (recN->SameName("@Halt0") && fromAdr == EP && !lastAdr) - break; - - DWORD dynAdr; - if (recN->SameName("@ClassCreate")) { - SetRegisterType(registers, 16, className); - SetFlag(cfSetA, curPos); - } - else if (recN->SameName("@CallDynaInst") || recN->SameName("@CallDynaClass")) { - if (DelphiVersion <= 5) - comment = GetDynaInfo(GetClassAdr(registers[16].type), registers[11].value, &dynAdr); // bx - else - comment = GetDynaInfo(GetClassAdr(registers[16].type), registers[14].value, &dynAdr); // si - AddPicode(curPos, OP_CALL, comment, dynAdr); - SetRegisterType(registers, 16, ""); - } - else if (recN->SameName("@FindDynaInst") || recN->SameName("@FindDynaClass")) { - comment = GetDynaInfo(GetClassAdr(registers[16].type), registers[10].value, &dynAdr); // dx - AddPicode(curPos, OP_CALL, comment, dynAdr); - SetRegisterType(registers, 16, ""); - } - // @XStrArrayClr - else if (recN->SameName("@LStrArrayClr") || recN->SameName("@WStrArrayClr") || recN->SameName("@UStrArrayClr")) { - DWORD arrAdr = registers[16].value; - int cnt = registers[18].value; - // Direct address??? - if (IsValidImageAdr(arrAdr)) { - } - // Local vars - else if ((registers[16].source & 0xDF) == 'L') { - recN1 = GetInfoRec(fromAdr); - int aofs = registers[16].value; - for (int aa = 0; aa < cnt; aa++, aofs += 4) { - if (recN->SameName("@LStrArrayClr")) - recN1->procInfo->AddLocal(aofs, 4, "", "AnsiString"); - else if (recN->SameName("@WStrArrayClr")) - recN1->procInfo->AddLocal(aofs, 4, "", "WideString"); - else if (recN->SameName("@UStrArrayClr")) - recN1->procInfo->AddLocal(aofs, 4, "", "UString"); - } - } - SetRegisterType(registers, 16, ""); - } - // @TryFinallyExit - else if (recN->SameName("@TryFinallyExit")) { - // Find first jxxx - for (Pos = curPos - 1; Pos >= fromPos; Pos--) { - b = Flags[Pos]; - if (b & cfInstruction) { - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo, 0); - if (DisInfo.Conditional) - break; - SetFlags(cfSkip | cfFinallyExit, Pos, instrLen1); - } - } - // @TryFinallyExit + jmp XXXXXXXX - instrLen += Disasm.Disassemble(Code + curPos + instrLen, (__int64)(Pos2Adr(curPos) + instrLen), &DisInfo, 0); - SetFlags(cfSkip | cfFinallyExit, curPos, instrLen); - } - else { - String retType = AnalyzeTypes(fromAdr, curPos, Adr, registers); - recN1 = GetInfoRec(fromAdr); - for (int mm = 16; mm <= 18; mm++) { - if (registers[mm].result == 1) { - if ((registers[mm].source & 0xDF) == 'L') { - recN1->procInfo->AddLocal((int)registers[mm].value, 4, "", registers[mm].type); - } - else if ((registers[mm].source & 0xDF) == 'A') - recN1->procInfo->AddArg(0x21, (int)registers[mm].value, 4, "", registers[mm].type); - } - } - SetRegisterType(registers, 16, retType); - } - } - } - else { - sp = -1; - SetRegisterType(registers, 16, ""); - } - } - // call Memory - else if (DisInfo.OpType[0] == otMEM && DisInfo.IndxReg == -1) { - sp = -1; - // call [Offset] - if (DisInfo.BaseReg == -1) { - } - // call [BaseReg + Offset] - else { - classAdr = registers[DisInfo.BaseReg].value; - SetRegisterType(registers, 16, ""); - if (IsValidCodeAdr(classAdr) && registers[DisInfo.BaseReg].source == 'V') { - recN = GetInfoRec(classAdr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - for (int mm = 0; mm < recN->vmtInfo->methods->Count; mm++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[mm]; - if (recM->kind == 'V' && recM->id == (int)DisInfo.Offset) { - recN1 = GetInfoRec(recM->address); - - if (recM->name != "") - comment = recM->name; - else { - if (recN1->HasName()) - comment = recN1->GetName(); - else - comment = GetClsName(classAdr) + ".sub_" + Val2Str8(recM->address); - } - AddPicode(curPos, OP_CALL, comment, recM->address); - - recN1->AddXref('V', fromAdr, curAdr - fromAdr); - if (recN1->kind == ikFunc) - SetRegisterType(registers, 16, recN1->type); - break; - } - } - } - registers[DisInfo.BaseReg].source = 0; - } - else { - int callOfs = DisInfo.Offset; - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (typeName != "" && callOfs > 0) { - Pos = GetNearestUpInstruction(curPos, fromPos, 1); - Adr = Pos2Adr(Pos); - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - if (DisInfo.Offset == callOfs + 4) { - fInfo = GetField(typeName, callOfs, &vmt, &vmtAdr, ""); - if (fInfo) { - if (fInfo->Name != "") - AddPicode(curPos, OP_CALL, typeName + "." + fInfo->Name, 0); - if (vmt) - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - else - delete fInfo; - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, callOfs, -1, "", ""); - if (fInfo) - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - } - } - } - } - } - } - SetRegisterSource(registers, 16, 0); - SetRegisterSource(registers, 17, 0); - SetRegisterSource(registers, 18, 0); - SetRegisterValue(registers, 16, 0xFFFFFFFF); - curPos += instrLen; - curAdr += instrLen; - continue; - } - sType = String(DisInfo.sSize); - // floating point operations - if (DisInfo.Float) { - float singleVal; - long double extendedVal; - String fVal = ""; - - switch (DisInfo.OpSize) { - case 4: - sType = "Single"; - break; - // Double or Comp??? - case 8: - sType = "Double"; - break; - case 10: - sType = "Extended"; - break; - default: - sType = "Float"; - break; - } - - Adr = DisInfo.Offset; - _ap = Adr2Pos(Adr); - // fxxx [Adr] - if (DisInfo.BaseReg == -1 && DisInfo.IndxReg == -1) { - if (IsValidImageAdr(Adr)) { - if (_ap >= 0) { - switch (DisInfo.OpSize) { - case 4: - singleVal = 0; - memmove((void*)&singleVal, Code + _ap, 4); - fVal = FloatToStr(singleVal); - break; - // Double or Comp??? - case 8: - break; - case 10: - try { - extendedVal = 0; - memmove((void*)&extendedVal, Code + _ap, 10); - fVal = FloatToStr(extendedVal); - } - catch (Exception &E) { - fVal = "Impossible!"; - } - break; - } - SetFlags(cfData, _ap, DisInfo.OpSize); - - recN = GetInfoRec(Adr); - if (!recN) - recN = new InfoRec(_ap, ikData); - if (!recN->HasName()) - recN->SetName(fVal); - if (recN->type == "") - recN->type = sType; - if (!IsValidCodeAdr(Adr)) - recN->AddXref('D', fromAdr, curAdr - fromAdr); - } - else { - recN = AddToBSSInfos(Adr, MakeGvarName(Adr), sType); - if (recN) - recN->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - else if (DisInfo.BaseReg != -1) { - // fxxxx [BaseReg + Offset] - if (DisInfo.IndxReg == -1) { - // fxxxx [ebp - Offset] - if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) { - recN1 = GetInfoRec(fromAdr); - recN1->procInfo->AddLocal((int)DisInfo.Offset, DisInfo.OpSize, "", sType); - } - // fxxx [esp + Offset] - else if (DisInfo.BaseReg == 20) { - dummy = 1; - } - else { - // fxxxx [BaseReg] - if (!DisInfo.Offset) { - varAdr = registers[DisInfo.BaseReg].value; - if (IsValidImageAdr(varAdr)) { - _ap = Adr2Pos(varAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(varAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, varAdr, curAdr); - recN1->type = sType; - if (!IsValidCodeAdr(varAdr)) - recN1->AddXref('D', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(varAdr, MakeGvarName(varAdr), sType); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - // fxxxx [BaseReg + Offset] - else if ((int)DisInfo.Offset > 0) { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (typeName != "") { - fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - if (vmt) { - if (CanReplace(fInfo->Type, sType)) - fInfo->Type = sType; - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - } - else - delete fInfo; - // if (vmtAdr) typeName = GetClsName(vmtAdr); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); - if (fInfo) { - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - } - } - } - // fxxxx [BaseReg - Offset] - else { - } - } - } - // fxxxx [BaseReg + IndxReg*Scale + Offset] - else { - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - // No operands - if (DisInfo.OpNum == 0) { - // cdq - if (op == OP_CDQ) { - SetRegisterSource(registers, 16, 'I'); - SetRegisterValue(registers, 16, 0xFFFFFFFF); - SetRegisterType(registers, 16, "Integer"); - SetRegisterSource(registers, 18, 'I'); - SetRegisterValue(registers, 18, 0xFFFFFFFF); - SetRegisterType(registers, 18, "Integer"); - } - } - // 1 operand - else if (DisInfo.OpNum == 1) { - // op Imm - if (DisInfo.OpType[0] == otIMM) { - if (IsValidImageAdr(DisInfo.Immediate)) { - _ap = Adr2Pos(DisInfo.Immediate); - if (_ap >= 0) { - recN1 = GetInfoRec(DisInfo.Immediate); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(DisInfo.Immediate, MakeGvarName(DisInfo.Immediate), ""); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - // op reg - else if (DisInfo.OpType[0] == otREG && op != OP_UNK && op != OP_PUSH) { - reg1Idx = DisInfo.OpRegIdx[0]; - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - // op [BaseReg + Offset] - else if (DisInfo.OpType[0] == otMEM) { - if (DisInfo.BaseReg != -1 && DisInfo.IndxReg == -1 && (int)DisInfo.Offset > 0) { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (typeName != "") { - fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - if (vmt) - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - else - delete fInfo; - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); - if (fInfo) { - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - } - } - } - if (op == OP_IMUL || op == OP_IDIV) { - SetRegisterSource(registers, 16, 0); - SetRegisterValue(registers, 16, 0xFFFFFFFF); - SetRegisterType(registers, 16, "Integer"); - SetRegisterSource(registers, 18, 0); - SetRegisterValue(registers, 18, 0xFFFFFFFF); - SetRegisterType(registers, 18, "Integer"); - } - } - } - // 2 or 3 operands - else if (DisInfo.OpNum >= 2) { - if (op & OP_A2) - // if (op == OP_MOV || op == OP_CMP || op == OP_LEA || op == OP_XOR || op == OP_ADD || op == OP_SUB || - // op == OP_AND || op == OP_TEST || op == OP_XCHG || op == OP_IMUL || op == OP_IDIV || op == OP_OR || - // op == OP_BT || op == OP_BTC || op == OP_BTR || op == OP_BTS) - { - if (DisInfo.OpType[0] == otREG) // cop reg,... - { - reg1Idx = DisInfo.OpRegIdx[0]; - source = registers[reg1Idx].source; - SetRegisterSource(registers, reg1Idx, 0); - - if (DisInfo.OpType[1] == otIMM) // cop reg, Imm - { - if (reset) { - typeName = TrimTypeName(registers[reg1Idx].type); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - - if (op == OP_ADD) { - if (typeName != "" && source != 'v') { - fInfo = GetField(typeName, (int)DisInfo.Immediate, &vmt, &vmtAdr, ""); - if (fInfo) { - registers[reg1Idx].type = fInfo->Type; - if (vmt) - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - else - delete fInfo; - // if (vmtAdr) typeName = GetClsName(vmtAdr); - AddPicode(curPos, 0, typeName, DisInfo.Immediate); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Immediate, -1, "", ""); - if (fInfo) { - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - AddPicode(curPos, 0, typeName, DisInfo.Immediate); - } - } - } - } - else { - if (op == OP_MOV) - SetRegisterValue(registers, reg1Idx, DisInfo.Immediate); - SetRegisterSource(registers, reg1Idx, 'I'); - if (IsValidImageAdr(DisInfo.Immediate)) { - _ap = Adr2Pos(DisInfo.Immediate); - if (_ap >= 0) { - recN1 = GetInfoRec(DisInfo.Immediate); - if (recN1) { - SetRegisterType(registers, reg1Idx, recN1->type); - bool _addXref = false; - switch (recN1->kind) { - case ikString: - SetRegisterType(registers, reg1Idx, "ShortString"); - _addXref = true; - break; - case ikLString: - SetRegisterType(registers, reg1Idx, "AnsiString"); - _addXref = true; - break; - case ikWString: - SetRegisterType(registers, reg1Idx, "WideString"); - _addXref = true; - break; - case ikCString: - SetRegisterType(registers, reg1Idx, "PAnsiChar"); - _addXref = true; - break; - case ikWCString: - SetRegisterType(registers, reg1Idx, "PWideChar"); - _addXref = true; - break; - case ikUString: - SetRegisterType(registers, reg1Idx, "UString"); - _addXref = true; - break; - } - if (_addXref) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - else { - recN1 = AddToBSSInfos(DisInfo.Immediate, MakeGvarName(DisInfo.Immediate), ""); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - } - } - else if (DisInfo.OpType[1] == otREG) // cop reg, reg - { - reg2Idx = DisInfo.OpRegIdx[1]; - if (reset) { - if (op == OP_MOV) { - SetRegisterSource(registers, reg1Idx, registers[reg2Idx].source); - SetRegisterValue(registers, reg1Idx, registers[reg2Idx].value); - SetRegisterType(registers, reg1Idx, registers[reg2Idx].type); - if (reg1Idx == 16) - fromIdx = reg2Idx; - } - else if (op == OP_XOR) { - SetRegisterValue(registers, reg1Idx, registers[reg1Idx].value ^ registers[reg2Idx].value); - SetRegisterType(registers, reg1Idx, ""); - } - else if (op == OP_XCHG) { - rtmp = registers[reg1Idx]; - registers[reg1Idx] = registers[reg2Idx]; - registers[reg2Idx] = rtmp; - } - else if (op == OP_IMUL || op == OP_IDIV) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - if (reg1Idx != reg2Idx) { - SetRegisterSource(registers, reg2Idx, 0); - SetRegisterValue(registers, reg2Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg2Idx, "Integer"); - } - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - } - else if (DisInfo.OpType[1] == otMEM) // cop reg, Memory - { - if (DisInfo.BaseReg == -1) { - if (DisInfo.IndxReg == -1) // cop reg, [Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - Adr = DisInfo.Offset; - if (IsValidImageAdr(Adr)) { - _ap = Adr2Pos(Adr); - if (_ap >= 0) { - recN = GetInfoRec(Adr); - if (recN) { - MakeGvar(recN, Adr, curAdr); - if (recN->kind == ikVMT) { - if (reset) { - SetRegisterType(registers, reg1Idx, recN->GetName()); - SetRegisterValue(registers, reg1Idx, Adr - VmtSelfPtr); - } - } - else { - if (reset) - registers[reg1Idx].type = recN->type; - if (reg1Idx < 24) { - if (reg1Idx >= 16) { - if (IsFlagSet(cfImport, _ap)) { - recN1 = GetInfoRec(Adr); - AddPicode(curPos, OP_COMMENT, recN1->GetName(), 0); - } - else if (!IsFlagSet(cfRTTI, _ap)) { - Val = *((DWORD*)(Code + _ap)); - if (reset) - SetRegisterValue(registers, reg1Idx, Val); - if (IsValidImageAdr(Val)) { - _ap = Adr2Pos(Val); - if (_ap >= 0) { - recN1 = GetInfoRec(Val); - if (recN1) { - MakeGvar(recN1, Val, curAdr); - varName = recN1->GetName(); - if (varName != "") - recN->SetName("^" + varName); - if (recN->type != "") - registers[reg1Idx].type = recN->type; - varType = recN1->type; - if (varType != "") { - recN->type = varType; - registers[reg1Idx].type = varType; - } - } - else { - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, Val, curAdr); - varName = recN1->GetName(); - if (varName != "") - recN->SetName("^" + varName); - if (recN->type != "") - registers[reg1Idx].type = recN->type; - } - if (recN) - recN->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - if (recN->HasName()) - recN1 = AddToBSSInfos(Val, recN->GetName(), recN->type); - else - recN1 = AddToBSSInfos(Val, MakeGvarName(Val), recN->type); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - else { - AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); - SetFlags(cfData, _ap, 4); - } - } - } - else { - if (reg1Idx <= 7) { - Val = *(Code + _ap); - } - else if (reg1Idx <= 15) { - Val = *((WORD*)(Code + _ap)); - } - AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); - SetFlags(cfData, _ap, 4); - } - } - } - } - else { - recN = new InfoRec(_ap, ikData); - MakeGvar(recN, Adr, curAdr); - if (reg1Idx < 24) { - if (reg1Idx >= 16) { - Val = *((DWORD*)(Code + _ap)); - if (reset) - SetRegisterValue(registers, reg1Idx, Val); - if (IsValidImageAdr(Val)) { - _ap = Adr2Pos(Val); - if (_ap >= 0) { - recN->kind = ikPointer; - recN1 = GetInfoRec(Val); - if (recN1) { - MakeGvar(recN1, Val, curAdr); - varName = recN1->GetName(); - if (varName != "" && (recN1->kind == ikLString || recN1->kind == ikWString || recN1->kind == ikUString)) - varName = "\"" + varName + "\""; - if (varName != "") - recN->SetName("^" + varName); - if (recN->type != "") - registers[reg1Idx].type = recN->type; - varType = recN1->type; - if (varType != "") { - recN->type = varType; - registers[reg1Idx].type = varType; - } - } - else { - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, Val, curAdr); - varName = recN1->GetName(); - if (varName != "" && (recN1->kind == ikLString || recN1->kind == ikWString || recN1->kind == ikUString)) - varName = "\"" + varName + "\""; - if (varName != "") - recN->SetName("^" + varName); - if (recN->type != "") - registers[reg1Idx].type = recN->type; - } - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(Val, MakeGvarName(Val), ""); - if (recN1) { - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - if (recN->type != "") - recN->type = recN1->type; - } - } - } - else { - AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); - SetFlags(cfData, _ap, 4); - } - } - else { - if (reg1Idx <= 7) { - Val = *(Code + _ap); - } - else if (reg1Idx <= 15) { - Val = *((WORD*)(Code + _ap)); - } - AddPicode(curPos, OP_COMMENT, "0x" + Val2Str0(Val), 0); - SetFlags(cfData, _ap, 4); - } - } - } - } - else { - recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - - } - } - else // cop reg, [Offset + IndxReg*Scale] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - - Adr = DisInfo.Offset; - if (IsValidImageAdr(Adr)) { - _ap = Adr2Pos(Adr); - if (_ap >= 0) { - recN = GetInfoRec(Adr); - if (recN) { - if (recN->kind == ikVMT) - typeName = recN->GetName(); - else - typeName = recN->type; - - if (reset) - SetRegisterType(registers, reg1Idx, typeName); - if (!IsValidCodeAdr(Adr)) - recN->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - else { - recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - } - else { - if (DisInfo.IndxReg == -1) { - if (bpBased && DisInfo.BaseReg == 21) // cop reg, [ebp + Offset] - { - if ((int)DisInfo.Offset < 0) // cop reg, [ebp - Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterSource(registers, reg1Idx, (op == OP_LEA) ? 'L' : 'l'); - SetRegisterValue(registers, reg1Idx, DisInfo.Offset); - SetRegisterType(registers, reg1Idx, ""); - } - } - // xchg ecx, [ebp-4] (ecx = 0, [ebp-4] = _ecx_) - if ((int)DisInfo.Offset == -4 && reg1Idx == 17) { - recN1 = GetInfoRec(fromAdr); - locInfo = recN1->procInfo->AddLocal((int)DisInfo.Offset, 4, "", ""); - SetRegisterType(registers, reg1Idx, _ecx_Type); - } - else { - recN1 = GetInfoRec(fromAdr); - locInfo = recN1->procInfo->AddLocal((int)DisInfo.Offset, DisInfo.OpSize, "", ""); - // mov, xchg - if (op == OP_MOV || op == OP_XCHG) { - SetRegisterType(registers, reg1Idx, locInfo->TypeDef); - } - else if (op == OP_LEA && locInfo->TypeDef != "") { - SetRegisterType(registers, reg1Idx, locInfo->TypeDef); - } - } - } - else // cop reg, [ebp + Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - if (bpBased && addArg) { - recN1 = GetInfoRec(fromAdr); - argInfo = recN1->procInfo->AddArg(0x21, DisInfo.Offset, 4, "", ""); - if (op == OP_MOV || op == OP_LEA || op == OP_XCHG) { - SetRegisterSource(registers, reg1Idx, (op == OP_LEA) ? 'A' : 'a'); - SetRegisterValue(registers, reg1Idx, DisInfo.Offset); - SetRegisterType(registers, reg1Idx, argInfo->TypeDef); - } - } - } - } - else if (DisInfo.BaseReg == 20) // cop reg, [esp + Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - } - else // cop reg, [BaseReg + Offset] - { - if (!DisInfo.Offset) // cop reg, [BaseReg] - { - Adr = registers[DisInfo.BaseReg].value; - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - - if (typeName != "") { - if (typeName[1] == '^') - typeName = typeName.SubString(2, typeName.Length() - 1); - SetRegisterValue(registers, reg1Idx, GetClassAdr(typeName)); - SetRegisterType(registers, reg1Idx, typeName); // ??? - SetRegisterSource(registers, reg1Idx, 'V'); // Virtual table base (for calls processing) - } - if (IsValidImageAdr(Adr)) { - _ap = Adr2Pos(Adr); - if (_ap >= 0) { - recN = GetInfoRec(Adr); - if (recN) { - if (recN->kind == ikVMT) { - SetRegisterType(registers, reg1Idx, recN->GetName()); - SetRegisterValue(registers, reg1Idx, Adr - VmtSelfPtr); - } - else { - SetRegisterType(registers, reg1Idx, recN->type); - if (recN->type != "") - SetRegisterValue(registers, reg1Idx, GetClassAdr(recN->type)); - } - } - } - else { - AddToBSSInfos(Adr, MakeGvarName(Adr), ""); - } - } - } - } - else if ((int)DisInfo.Offset > 0) // cop reg, [BaseReg + Offset] - { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - sType = "Integer"; - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - if (typeName != "") { - fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - if (op == OP_MOV || op == OP_XCHG) { - registers[reg1Idx].type = fInfo->Type; - } - if (vmt) { - if (CanReplace(fInfo->Type, sType)) - fInfo->Type = sType; - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - } - else - delete fInfo; - // if (vmtAdr) typeName = GetClsName(vmtAdr); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); - if (fInfo) { - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - } - } - } - else // cop reg, [BaseReg - Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - } - } - } - else // cop reg, [BaseReg + IndxReg*Scale + Offset] - { - if (DisInfo.BaseReg == 21) // cop reg, [ebp + IndxReg*Scale + Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - } - else if (DisInfo.BaseReg == 20) // cop reg, [esp + IndxReg*Scale + Offset] - { - if (reset) { - if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - } - else // cop reg, [BaseReg + IndxReg*Scale + Offset] - { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (reset) { - if (op == OP_LEA) { - // BaseReg - points to class - if (typeName != "") { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - // Else - general arifmetics - else { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - } - else if (op == OP_IMUL) { - SetRegisterSource(registers, reg1Idx, 0); - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, "Integer"); - } - else { - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - SetRegisterType(registers, reg1Idx, ""); - } - } - } - } - } - } - } - // cop Mem,... - else { - // cop Mem, Imm - if (DisInfo.OpType[1] == otIMM) { - // cop [Offset], Imm - if (DisInfo.BaseReg == -1 && DisInfo.IndxReg == -1) { - Adr = DisInfo.Offset; - if (IsValidImageAdr(Adr)) { - _ap = Adr2Pos(Adr); - if (_ap >= 0) { - recN1 = GetInfoRec(Adr); - if (!recN1) - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, Adr, curAdr); - if (!IsValidCodeAdr(Adr)) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - // cop [BaseReg + IndxReg*Scale + Offset], Imm - else if (DisInfo.BaseReg != -1) { - // cop [BaseReg + Offset], Imm - if (DisInfo.IndxReg == -1) { - // cop [ebp - Offset], Imm - if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) { - recN1 = GetInfoRec(fromAdr); - recN1->procInfo->AddLocal((int)DisInfo.Offset, DisInfo.OpSize, "", ""); - } - // cop [esp], Imm - else if (DisInfo.BaseReg == 20) { - dummy = 1; - } - // other registers - else { - // cop [BaseReg], Imm - if (!DisInfo.Offset) { - Adr = registers[DisInfo.BaseReg].value; - if (IsValidImageAdr(Adr)) { - _ap = Adr2Pos(Adr); - if (_ap >= 0) { - recN = GetInfoRec(Adr); - if (!recN) - recN = new InfoRec(_ap, ikData); - MakeGvar(recN, Adr, curAdr); - if (!IsValidCodeAdr(Adr)) - recN->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(Adr, MakeGvarName(Adr), ""); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - // cop [BaseReg + Offset], Imm - else if ((int)DisInfo.Offset > 0) { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (typeName != "") { - fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - if (vmt) { - if (op != OP_CMP && op != OP_TEST) - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); - else - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - } - else - delete fInfo; - // if (vmtAdr) typeName = GetClsName(vmtAdr); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); - if (fInfo) { - if (op != OP_CMP && op != OP_TEST) - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); - else - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'C'); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - } - } - } - // cop [BaseReg - Offset], Imm - else { - } - } - } - // cop [BaseReg + IndxReg*Scale + Offset], Imm - else { - } - } - // Other instructions - else { - } - } - // cop Mem, reg - else if (DisInfo.OpType[1] == otREG) { - reg2Idx = DisInfo.OpRegIdx[1]; - // op [Offset], reg - if (DisInfo.BaseReg == -1 && DisInfo.IndxReg == -1) { - varAdr = DisInfo.Offset; - if (IsValidImageAdr(varAdr)) { - _ap = Adr2Pos(varAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(varAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, varAdr, curAdr); - if (op == OP_MOV) { - if (registers[reg2Idx].type != "") - recN1->type = registers[reg2Idx].type; - } - if (!IsValidCodeAdr(varAdr)) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(varAdr, MakeGvarName(varAdr), registers[reg2Idx].type); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - } - // cop [BaseReg + IndxReg*Scale + Offset], reg - else if (DisInfo.BaseReg != -1) { - if (DisInfo.IndxReg == -1) { - // cop [ebp - Offset], reg - if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) { - recN1 = GetInfoRec(fromAdr); - recN1->procInfo->AddLocal((int)DisInfo.Offset, 4, "", registers[reg2Idx].type); - } - // esp - else if (DisInfo.BaseReg == 20) { - } - // other registers - else { - // cop [BaseReg], reg - if (!DisInfo.Offset) { - varAdr = registers[DisInfo.BaseReg].value; - if (IsValidImageAdr(varAdr)) { - _ap = Adr2Pos(varAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(varAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, varAdr, curAdr); - if (recN1->type == "") - recN1->type = registers[reg2Idx].type; - if (!IsValidCodeAdr(varAdr)) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - else { - recN1 = AddToBSSInfos(varAdr, MakeGvarName(varAdr), registers[reg2Idx].type); - if (recN1) - recN1->AddXref('C', fromAdr, curAdr - fromAdr); - } - } - else { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (typeName != "") { - if (registers[reg2Idx].type != "") - sType = registers[reg2Idx].type; - fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - if (vmt) { - if (CanReplace(fInfo->Type, sType)) - fInfo->Type = sType; - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); - } - else - delete fInfo; - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); - if (fInfo) { - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - } - } - } - } - // cop [BaseReg + Offset], reg - else if ((int)DisInfo.Offset > 0) { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - if (typeName != "") { - if (registers[reg2Idx].type != "") - sType = registers[reg2Idx].type; - fInfo = GetField(typeName, (int)DisInfo.Offset, &vmt, &vmtAdr, ""); - if (fInfo) { - if (vmt) { - if (CanReplace(fInfo->Type, sType)) - fInfo->Type = sType; - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); - } - else - delete fInfo; - // if (vmtAdr) typeName = GetClsName(vmtAdr); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - else if (vmt) { - fInfo = AddField(fromAdr, curAdr - fromAdr, typeName, FIELD_PUBLIC, (int)DisInfo.Offset, -1, "", sType); - if (fInfo) { - AddFieldXref(fInfo, fromAdr, curAdr - fromAdr, 'c'); - AddPicode(curPos, 0, typeName, DisInfo.Offset); - } - } - } - } - // cop [BaseReg - Offset], reg - else { - } - } - } - // cop [BaseReg + IndxReg*Scale + Offset], reg - else { - // cop [BaseReg + IndxReg*Scale + Offset], reg - if (bpBased && DisInfo.BaseReg == 21 && (int)DisInfo.Offset < 0) { - } - // esp - else if (DisInfo.BaseReg == 20) { - } - // other registers - else { - // [BaseReg] - if (!DisInfo.Offset) { - } - // cop [BaseReg + IndxReg*Scale + Offset], reg - else if ((int)DisInfo.Offset > 0) { - typeName = TrimTypeName(registers[DisInfo.BaseReg].type); - } - // cop [BaseReg - Offset], reg - else { - } - } - } - } - // Other instructions - else { - } - } - } - } - else if (op == OP_ADC || op == OP_SBB) { - if (DisInfo.OpType[0] == otREG) { - reg1Idx = DisInfo.OpRegIdx[0]; - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - registers[reg1Idx].type = ""; - } - } - else if (op == OP_MUL || op == OP_DIV) { - // Clear register eax - SetRegisterValue(registers, 16, 0xFFFFFFFF); - for (n = 0; n <= 16; n += 4) { - if (n == 12) - continue; - registers[n].type = ""; - } - // Clear register edx - SetRegisterValue(registers, 18, 0xFFFFFFFF); - for (n = 2; n <= 18; n += 4) { - if (n == 14) - continue; - registers[n].type = ""; - } - } - else { - if (DisInfo.OpType[0] == otREG) { - reg1Idx = DisInfo.OpRegIdx[0]; - if ((registers[reg1Idx].source & 0xDF) != 'L') - SetRegisterValue(registers, reg1Idx, 0xFFFFFFFF); - registers[reg1Idx].type = ""; - } - } - // SHL??? SHR??? - } - curPos += instrLen; - curAdr += instrLen; - } - return fContinue; -} - -// --------------------------------------------------------------------------- -String __fastcall TFMain_11011981::AnalyzeTypes(DWORD parentAdr, int callPos, DWORD callAdr, PRINFO registers) { - WORD codePage, elemSize = 1; - int n, wBytes, pos, pushn, itemPos, refcnt, len, regIdx; - int _idx, _ap, _kind, _size, _pos; - DWORD itemAdr, strAdr; - char *tmpBuf; - PInfoRec recN, recN1; - PARGINFO argInfo; - String typeDef, typeName, retName, _vs; - DISINFO _disInfo; - char buf[1024]; // for LoadStr function - - _ap = Adr2Pos(callAdr); - if (_ap < 0) - return ""; - - retName = ""; - recN = GetInfoRec(callAdr); - // If procedure is skipped return - if (IsFlagSet(cfSkip, callPos)) { - // @BeforeDestruction - if (recN->SameName("@BeforeDestruction")) - return registers[16].type; - - return recN->type; - } - - // cdecl, stdcall - if (recN->procInfo->flags & 1) { - if (!recN->procInfo->args || !recN->procInfo->args->Count) { - return recN->type; - } - - for (pos = callPos, pushn = -1; ; pos--) { - if (!IsFlagSet(cfInstruction, pos)) - continue; - if (IsFlagSet(cfProcStart, pos)) - break; - // I cannot yet handle this situation - if (IsFlagSet(cfCall, pos) && pos != callPos) - break; - if (IsFlagSet(cfPush, pos)) { - pushn++; - if (pushn < recN->procInfo->args->Count) { - Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - itemAdr = _disInfo.Immediate; - if (IsValidImageAdr(itemAdr)) { - itemPos = Adr2Pos(itemAdr); - argInfo = (PARGINFO)recN->procInfo->args->Items[pushn]; - typeDef = argInfo->TypeDef; - - if (SameText(typeDef, "PAnsiChar") || SameText(typeDef, "PChar")) { - if (itemPos >= 0) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - // var - use pointer - if (argInfo->Tag == 0x22) { - strAdr = *((DWORD*)(Code + itemPos)); - if (!strAdr) { - SetFlags(cfData, itemPos, 4); - MakeGvar(recN1, itemAdr, Pos2Adr(pos)); - if (typeDef != "") - recN1->type = typeDef; - } - else { - _ap = Adr2Pos(strAdr); - if (_ap >= 0) { - len = strlen((char*)(Code + _ap)); - SetFlags(cfData, _ap, len + 1); - } - else if (_ap == -1) { - recN1 = AddToBSSInfos(strAdr, MakeGvarName(strAdr), typeDef); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - } - // val - else if (argInfo->Tag == 0x21) { - recN1->kind = ikCString; - len = strlen(Code + itemPos); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - recN1->SetName(TransformString(Code + itemPos, len)); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - SetFlags(cfData, itemPos, len + 1); - } - if (recN1) - recN1->ScanUpItemAndAddRef(callPos, itemAdr, 'C', parentAdr); - } - else { - recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - else if (SameText(typeDef, "PWideChar")) { - if (itemPos) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - // var - use pointer - if (argInfo->Tag == 0x22) { - strAdr = *((DWORD*)(Code + itemPos)); - if (!strAdr) { - SetFlags(cfData, itemPos, 4); - MakeGvar(recN1, itemAdr, Pos2Adr(pos)); - if (typeDef != "") - recN1->type = typeDef; - } - else { - _ap = Adr2Pos(strAdr); - if (_ap >= 0) { - len = wcslen((wchar_t*)(Code + Adr2Pos(strAdr))); - SetFlags(cfData, Adr2Pos(strAdr), 2*len + 1); - } - else if (_ap == -1) { - recN1 = AddToBSSInfos(strAdr, MakeGvarName(strAdr), typeDef); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - } - // val - else if (argInfo->Tag == 0x21) { - recN1->kind = ikWCString; - len = wcslen((wchar_t*)(Code + itemPos)); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - WideString wStr = WideString((wchar_t*)(Code + itemPos)); - int size = WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, 0, 0, 0, 0); - if (size) { - tmpBuf = new char[size + 1]; - WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, (LPSTR)tmpBuf, size, 0, 0); - recN1->SetName(TransformString(tmpBuf, size)); - delete[]tmpBuf; - if (recN->SameName("GetProcAddress")) - retName = recN1->GetName(); - } - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - SetFlags(cfData, itemPos, 2*len + 1); - } - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - else if (SameText(typeDef, "TGUID")) { - if (itemPos) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikGUID); - recN1->kind = ikGUID; - SetFlags(cfData, itemPos, 16); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - recN1->SetName(Guid2String(Code + itemPos)); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - } - if (pushn == recN->procInfo->args->Count - 1) - break; - } - } - } - return recN->type; - } - if (recN->HasName()) { - if (recN->SameName("LoadStr") || recN->SameName("FmtLoadStr") || recN->SameName("LoadResString")) { - int ident = registers[16].value; // eax = string ID - if (ident != -1) { - HINSTANCE hInst = LoadLibraryEx(AnsiString(SourceFile).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); - if (hInst) { - int bytes = LoadString(hInst, (UINT)ident, buf, 1024); - if (bytes) - AddPicode(callPos, OP_COMMENT, "'" + String(buf, bytes) + "'", 0); - FreeLibrary(hInst); - } - } - return ""; - } - if (recN->SameName("TApplication.CreateForm")) { - DWORD vmtAdr = registers[18].value + VmtSelfPtr; // edx - - DWORD refAdr = registers[17].value; // ecx - if (IsValidImageAdr(refAdr)) { - typeName = GetClsName(vmtAdr); - _ap = Adr2Pos(refAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(refAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikData); - MakeGvar(recN1, refAdr, 0); - if (typeName != "") - recN1->type = typeName; - } - else { - _vs = Val2Str8(refAdr); - _idx = BSSInfos->IndexOf(_vs); - if (_idx != -1) { - recN1 = (PInfoRec)BSSInfos->Objects[_idx]; - if (typeName != "") - recN1->type = typeName; - } - } - } - return ""; - } - if (recN->SameName("@FinalizeRecord")) { - DWORD recAdr = registers[16].value; // eax - DWORD recTypeAdr = registers[18].value; // edx - typeName = GetTypeName(recTypeAdr); - // Address given directly - if (IsValidImageAdr(recAdr)) { - _ap = Adr2Pos(recAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(recAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikRecord); - MakeGvar(recN1, recAdr, 0); - if (typeName != "") - recN1->type = typeName; - if (!IsValidCodeAdr(recAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(recAdr, MakeGvarName(recAdr), typeName); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - // Local variable - else if ((registers[16].source & 0xDF) == 'L') { - if (registers[16].type == "" && typeName != "") - registers[16].type = typeName; - registers[16].result = 1; - } - return ""; - } - if (recN->SameName("@DynArrayAddRef")) { - DWORD arrayAdr = registers[16].value; // eax - // Address given directly - if (IsValidImageAdr(arrayAdr)) { - _ap = Adr2Pos(arrayAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(arrayAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikDynArray); - MakeGvar(recN1, arrayAdr, 0); - if (!IsValidCodeAdr(arrayAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), ""); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - // Local variable - else if ((registers[16].source & 0xDF) == 'L') { - if (registers[16].type == "") - registers[16].type = "array of ?"; - registers[16].result = 1; - } - return ""; - } - if (recN->SameName("DynArrayClear") || recN->SameName("@DynArrayClear") || recN->SameName("DynArraySetLength") || recN->SameName("@DynArraySetLength")) { - DWORD arrayAdr = registers[16].value; // eax - DWORD elTypeAdr = registers[18].value; // edx - typeName = GetTypeName(elTypeAdr); - // Address given directly - if (IsValidImageAdr(arrayAdr)) { - _ap = Adr2Pos(arrayAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(arrayAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikDynArray); - MakeGvar(recN1, arrayAdr, 0); - if (recN1->type == "" && typeName != "") - recN1->type = typeName; - if (!IsValidCodeAdr(arrayAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), typeName); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - // Local variable - else if ((registers[16].source & 0xDF) == 'L') { - if (registers[16].type == "" && typeName != "") - registers[16].type = typeName; - registers[16].result = 1; - } - return ""; - } - if (recN->SameName("@DynArrayCopy")) { - DWORD arrayAdr = registers[16].value; // eax - DWORD elTypeAdr = registers[18].value; // edx - DWORD dstArrayAdr = registers[17].value; // ecx - typeName = GetTypeName(elTypeAdr); - // Address given directly - if (IsValidImageAdr(arrayAdr)) { - _ap = Adr2Pos(arrayAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(arrayAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikDynArray); - MakeGvar(recN1, arrayAdr, 0); - if (typeName != "") - recN1->type = typeName; - if (!IsValidCodeAdr(arrayAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), typeName); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - // Local variable - else if ((registers[16].source & 0xDF) == 'L') { - if (registers[16].type == "" && typeName != "") - registers[16].type = typeName; - registers[16].result = 1; - } - // Address given directly - if (IsValidImageAdr(dstArrayAdr)) { - _ap = Adr2Pos(dstArrayAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(dstArrayAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikDynArray); - MakeGvar(recN1, dstArrayAdr, 0); - if (typeName != "") - recN1->type = typeName; - if (!IsValidCodeAdr(dstArrayAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(dstArrayAdr, MakeGvarName(dstArrayAdr), typeName); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - // Local variable - else if ((registers[17].source & 0xDF) == 'L') { - if (registers[17].type == "" && typeName != "") - registers[17].type = typeName; - registers[17].result = 1; - } - return ""; - } - if (recN->SameName("@IntfClear")) { - DWORD intfAdr = registers[16].value; // eax - - if (IsValidImageAdr(intfAdr)) { - _ap = Adr2Pos(intfAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(intfAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikInterface); - MakeGvar(recN1, intfAdr, 0); - recN1->type = "IInterface"; - if (!IsValidCodeAdr(intfAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(intfAdr, MakeGvarName(intfAdr), "IInterface"); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - return ""; - } - if (recN->SameName("@FinalizeArray")) { - DWORD arrayAdr = registers[16].value; // eax - int elNum = registers[17].value; // ecx - DWORD elTypeAdr = registers[18].value; // edx - - if (IsValidImageAdr(arrayAdr)) { - typeName = "array[" + String(elNum) + "] of " + GetTypeName(elTypeAdr); - _ap = Adr2Pos(arrayAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(arrayAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikArray); - MakeGvar(recN1, arrayAdr, 0); - recN1->type = typeName; - if (!IsValidCodeAdr(arrayAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(arrayAdr, MakeGvarName(arrayAdr), typeName); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - return ""; - } - if (recN->SameName("@VarClr")) { - DWORD strAdr = registers[16].value; // eax - if (IsValidImageAdr(strAdr)) { - _ap = Adr2Pos(strAdr); - if (_ap >= 0) { - recN1 = GetInfoRec(strAdr); - if (!recN1) - recN1 = new InfoRec(_ap, ikVariant); - MakeGvar(recN1, strAdr, 0); - recN1->type = "Variant"; - if (!IsValidCodeAdr(strAdr)) - recN1->AddXref('C', callAdr, callPos); - } - else { - recN1 = AddToBSSInfos(strAdr, MakeGvarName(strAdr), "Variant"); - if (recN1) - recN1->AddXref('C', callAdr, callPos); - } - } - return ""; - } - // @AsClass - if (recN->SameName("@AsClass")) { - return registers[18].type; - } - // @IsClass - if (recN->SameName("@IsClass")) { - return ""; - } - // @GetTls - if (recN->SameName("@GetTls")) { - return "#TLS"; - } - // @AfterConstruction - if (recN->SameName("@AfterConstruction")) - return ""; - } - // try prototype - BYTE callKind = recN->procInfo->flags & 7; - if (recN->procInfo->args && !callKind) { - registers[16].result = 0; - registers[17].result = 0; - registers[18].result = 0; - - for (n = 0; n < recN->procInfo->args->Count; n++) { - argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - regIdx = -1; - if (argInfo->Ndx == 0) // eax - regIdx = 16; - else if (argInfo->Ndx == 1) // edx - regIdx = 18; - else if (argInfo->Ndx == 2) // ecx - regIdx = 17; - if (regIdx == -1) - continue; - if (argInfo->TypeDef == "") { - if (registers[regIdx].type != "") - argInfo->TypeDef = TrimTypeName(registers[regIdx].type); - } - else { - if (registers[regIdx].type == "") { - registers[regIdx].type = argInfo->TypeDef; - // registers[regIdx].result = 1; - } - else { - typeName = GetCommonType(argInfo->TypeDef, TrimTypeName(registers[regIdx].type)); - if (typeName != "") - argInfo->TypeDef = typeName; - } - // Aliases ??????????? - } - - typeDef = argInfo->TypeDef; - // Local var (lea - remove ^ before type) - if (registers[regIdx].source == 'L') { - if (SameText(typeDef, "Pointer")) - registers[regIdx].type = "Byte"; - else if (SameText(typeDef, "PAnsiChar") || SameText(typeDef, "PChar")) - registers[regIdx].type = typeDef.SubString(2, typeDef.Length() - 1); - else if (DelphiVersion >= 2009 && SameText(typeDef, "AnsiString")) - registers[regIdx].type = "UnicodeString"; - - registers[regIdx].result = 1; - continue; - } - // Local var - if (registers[regIdx].source == 'l') { - continue; - } - // Arg - if ((registers[regIdx].source & 0xDF) == 'A') { - continue; - } - itemAdr = registers[regIdx].value; - if (IsValidImageAdr(itemAdr)) { - itemPos = Adr2Pos(itemAdr); - if (itemPos >= 0) { - recN1 = GetInfoRec(itemAdr); - if (!recN1 || recN1->kind != ikVMT) { - registers[regIdx].result = 1; - - if (SameText(typeDef, "PShortString") || SameText(typeDef, "ShortString")) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - // var - use pointer - if (argInfo->Tag == 0x22) { - strAdr = *((DWORD*)(Code + itemPos)); - if (IsValidCodeAdr(strAdr)) { - _ap = Adr2Pos(strAdr); - len = *(Code + _ap); - SetFlags(cfData, _ap, len + 1); - } - else { - SetFlags(cfData, itemPos, 4); - MakeGvar(recN1, itemAdr, 0); - if (typeDef != "") - recN1->type = typeDef; - } - } - // val - else if (argInfo->Tag == 0x21) { - recN1->kind = ikString; - len = *(Code + itemPos); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - recN1->SetName(TransformString(Code + itemPos + 1, len)); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - SetFlags(cfData, itemPos, len + 1); - } - } - else if (SameText(typeDef, "PAnsiChar") || SameText(typeDef, "PChar")) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - // var - use pointer - if (argInfo->Tag == 0x22) { - strAdr = *((DWORD*)(Code + itemPos)); - if (IsValidCodeAdr(strAdr)) { - _ap = Adr2Pos(strAdr); - len = strlen(Code + _ap); - SetFlags(cfData, _ap, len + 1); - } - else { - SetFlags(cfData, itemPos, 4); - MakeGvar(recN1, itemAdr, 0); - if (typeDef != "") - recN1->type = typeDef; - } - } - // val - else if (argInfo->Tag == 0x21) { - recN1->kind = ikCString; - len = strlen(Code + itemPos); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - recN1->SetName(TransformString(Code + itemPos, len)); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - SetFlags(cfData, itemPos, len + 1); - } - } - else if (SameText(typeDef, "AnsiString") || SameText(typeDef, "String") || SameText(typeDef, "UString") || SameText(typeDef, "UnicodeString")) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - // var - use pointer - if (argInfo->Tag == 0x22) { - strAdr = *((DWORD*)(Code + itemPos)); - _ap = Adr2Pos(strAdr); - if (IsValidCodeAdr(strAdr)) { - refcnt = *((int*)(Code + _ap - 8)); - len = *((int*)(Code + _ap - 4)); - if (refcnt == -1 && len >= 0 && len < 25000) { - if (DelphiVersion < 2009) { - SetFlags(cfData, _ap - 8, (8 + len + 1 + 3) & (-4)); - } - else { - codePage = *((WORD*)(Code + _ap - 12)); - elemSize = *((WORD*)(Code + _ap - 10)); - SetFlags(cfData, _ap - 12, (12 + (len + 1)*elemSize + 3) & (-4)); - } - } - else { - SetFlags(cfData, _ap, 4); - } - } - else { - if (_ap >= 0) { - SetFlags(cfData, itemPos, 4); - MakeGvar(recN1, itemAdr, 0); - if (typeDef != "") - recN1->type = typeDef; - } - else if (_ap == -1) { - recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); - } - } - } - // val - else if (argInfo->Tag == 0x21) { - refcnt = *((int*)(Code + itemPos - 8)); - len = wcslen((wchar_t*)(Code + itemPos)); - if (DelphiVersion < 2009) { - recN1->kind = ikLString; - } - else { - codePage = *((WORD*)(Code + itemPos - 12)); - elemSize = *((WORD*)(Code + itemPos - 10)); - recN1->kind = ikUString; - } - if (refcnt == -1 && len >= 0 && len < 25000) { - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - if (DelphiVersion < 2009) - recN1->SetName(TransformString(Code + itemPos, len)); - else - recN1->SetName(TransformUString(codePage, (wchar_t*)(Code + itemPos), len)); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - if (DelphiVersion < 2009) - SetFlags(cfData, itemPos - 8, (8 + len + 1 + 3) & (-4)); - else - SetFlags(cfData, itemPos - 12, (12 + (len + 1)*elemSize + 3) & (-4)); - } - else { - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - recN1->SetName(""); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - SetFlags(cfData, itemPos, 4); - } - } - } - else if (SameText(typeDef, "WideString")) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - // var - use pointer - if (argInfo->Tag == 0x22) { - strAdr = *((DWORD*)(Code + itemPos)); - _ap = Adr2Pos(strAdr); - if (IsValidCodeAdr(strAdr)) { - len = *((int*)(Code + _ap - 4)); - SetFlags(cfData, _ap - 4, (4 + len + 1 + 3) & (-4)); - } - else { - if (_ap >= 0) { - SetFlags(cfData, itemPos, 4); - MakeGvar(recN1, itemAdr, 0); - if (typeDef != "") - recN1->type = typeDef; - } - else if (_ap == -1) { - recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); - } - } - } - // val - else if (argInfo->Tag == 0x21) { - recN1->kind = ikWString; - len = wcslen((wchar_t*)(Code + itemPos)); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - WideString wStr = WideString((wchar_t*)(Code + itemPos)); - int size = WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, 0, 0, 0, 0); - if (size) { - tmpBuf = new BYTE[size + 1]; - WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), len, (LPSTR)tmpBuf, size, 0, 0); - recN1->SetName(TransformString(tmpBuf, size)); // ???size - 1 - delete[]tmpBuf; - } - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - SetFlags(cfData, itemPos - 4, (4 + len + 1 + 3) & (-4)); - } - } - else if (SameText(typeDef, "TGUID")) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikGUID); - recN1->kind = ikGUID; - SetFlags(cfData, itemPos, 16); - if (!recN1->HasName()) { - if (IsValidCodeAdr(itemAdr)) { - recN1->SetName(Guid2String(Code + itemPos)); - } - else { - recN1->SetName(MakeGvarName(itemAdr)); - if (typeDef != "") - recN1->type = typeDef; - } - } - } - else if (SameText(typeDef, "PResStringRec")) { - recN1 = GetInfoRec(itemAdr); - if (!recN1) { - recN1 = new InfoRec(itemPos, ikResString); - recN1->type = "TResStringRec"; - recN1->ConcatName("SResString" + String(LastResStrNo)); - LastResStrNo++; - // Set Flags - SetFlags(cfData, itemPos, 8); - // Get Context - HINSTANCE hInst = LoadLibraryEx(AnsiString(SourceFile).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); - if (hInst) { - DWORD resid = *((DWORD*)(Code + itemPos + 4)); - if (resid < 0x10000) { - int Bytes = LoadString(hInst, (UINT)resid, buf, 1024); - recN1->rsInfo->value = String(buf, Bytes); - } - FreeLibrary(hInst); - } - } - } - else { - recN1 = GetInfoRec(itemAdr); - if (!recN1) - recN1 = new InfoRec(itemPos, ikData); - if (!recN1->HasName() && recN1->kind != ikProc && recN1->kind != ikFunc && recN1->kind != ikConstructor && recN1->kind != ikDestructor && recN1->kind != ikRefine) { - if (typeDef != "") - recN1->type = typeDef; - } - } - } - } - else { - _kind = GetTypeKind(typeDef, &_size); - if (_kind == ikInteger || _kind == ikChar || _kind == ikEnumeration || _kind == ikFloat || _kind == ikSet || _kind == ikWChar) { - _idx = BSSInfos->IndexOf(Val2Str8(itemAdr)); - if (_idx != -1) { - recN1 = (PInfoRec)BSSInfos->Objects[_idx]; - delete recN1; - BSSInfos->Delete(_idx); - } - } - else { - recN1 = AddToBSSInfos(itemAdr, MakeGvarName(itemAdr), typeDef); - } - } - } - } - } - if (recN->kind == ikFunc) { - return recN->type; - } - return ""; -} -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// *************************************************************************** -// AnalyzeArguments -// *************************************************************************** -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -String __fastcall TFMain_11011981::AnalyzeArguments(DWORD fromAdr) { - BYTE op; - bool kb; - bool bpBased; - bool emb, lastemb; - bool argA, argD, argC; - bool inA, inD, inC; - bool spRestored = false; - WORD bpBase, retBytes; - int num, instrLen, instrLen1, instrLen2, _procSize; - int firstPopRegIdx = -1, popBytes = 0, procStackSize = 0; - int fromPos, curPos, Pos, reg1Idx, reg2Idx, sSize; - DWORD b, curAdr, Adr, Adr1; - DWORD lastAdr = 0, lastCallAdr = 0, lastMovAdr = 0, lastMovImm = 0; - PInfoRec recN, recN1; - PARGINFO argInfo; - DWORD stack[256]; - int sp = -1; - int macroFrom, macroTo; - String minClassName, className = "", retType = ""; - DISINFO DisInfo, DisInfo1; - - fromPos = Adr2Pos(fromAdr); - if (fromPos < 0) - return ""; - if (IsFlagSet(cfEmbedded, fromPos)) - return ""; - if (IsFlagSet(cfExport, fromPos)) - return ""; - - recN = GetInfoRec(fromAdr); - if (!recN || !recN->procInfo) - return ""; - - // If cfPass is set exit - if (IsFlagSet(cfPass, fromPos)) - return recN->type; - - // Proc start - SetFlag(cfProcStart | cfPass, fromPos); - - // Skip Imports - if (IsFlagSet(cfImport, fromPos)) - return recN->type; - - kb = (recN->procInfo->flags & PF_KBPROTO); - bpBased = (recN->procInfo->flags & PF_BPBASED); - emb = (recN->procInfo->flags & PF_EMBED); - bpBase = recN->procInfo->bpBase; - retBytes = recN->procInfo->retBytes; - - // If constructor or destructor get class name - if (recN->kind == ikConstructor || recN->kind == ikDestructor) - className = ExtractClassName(recN->GetName()); - // If ClassName not given and proc is dynamic, try to find minimal class - if (className == "" && (recN->procInfo->flags & PF_DYNAMIC) && recN->xrefs) { - minClassName = ""; - for (int n = 0; n < recN->xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; - if (recX->type == 'D') { - className = GetClsName(recX->adr); - if (minClassName == "" || !IsInheritsByClassName(className, minClassName)) - minClassName = className; - } - } - if (minClassName != "") - className = minClassName; - } - // If ClassName not given and proc is virtual, try to find minimal class - if (className == "" && (recN->procInfo->flags & PF_VIRTUAL) && recN->xrefs) { - minClassName = ""; - for (int n = 0; n < recN->xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; - if (recX->type == 'D') { - className = GetClsName(recX->adr); - if (minClassName == "" || !IsInheritsByClassName(className, minClassName)) - minClassName = className; - } - } - if (minClassName != "") - className = minClassName; - } - - argA = argD = argC = true; // On entry - inA = inD = inC = false; // No arguments - - _procSize = GetProcSize(fromAdr); - curPos = fromPos; - curAdr = fromAdr; - - while (1) { - if (curAdr >= CodeBase + TotalSize) - break; - // Skip exception table - if (IsFlagSet(cfETable, curPos)) { - // dd num - num = *((int*)(Code + curPos)); - curPos += 4 + 8 * num; - curAdr += 4 + 8 * num; - continue; - } - - BYTE b1 = Code[curPos]; - BYTE b2 = Code[curPos + 1]; - if (!b1 && !b2 && !lastAdr) - break; - - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo, 0); - // if (!instrLen) break; - if (!instrLen) { - curPos++; - curAdr++; - continue; - } - - op = Disasm.GetOp(DisInfo.Mnem); - // Code - SetFlags(cfCode, curPos, instrLen); - // Instruction begin - SetFlag(cfInstruction, curPos); - - if (curAdr >= lastAdr) - lastAdr = 0; - - if (op == OP_JMP) { - if (curAdr == fromAdr) - break; - if (DisInfo.OpType[0] == otMEM) { - if (Adr2Pos(DisInfo.Offset) < 0 && (!lastAdr || curAdr == lastAdr)) - break; - } - if (DisInfo.OpType[0] == otIMM) { - Adr = DisInfo.Immediate; - if (Adr2Pos(Adr) < 0 && (!lastAdr || curAdr == lastAdr)) - break; - if (GetSegmentNo(Adr) != 0 && GetSegmentNo(fromAdr) != GetSegmentNo(Adr) && (!lastAdr || curAdr == lastAdr)) - break; - if (Adr < fromAdr && (!lastAdr || curAdr == lastAdr)) - break; - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - - if (DisInfo.Ret) { - // End of proc - if (!lastAdr || curAdr == lastAdr) { - // Get last instruction - curPos -= instrLen; - if ((DisInfo.Ret && !IsFlagSet(cfSkip, curPos)) || // ret not in SEH - IsFlagSet(cfCall, curPos)) // @Halt0 - { - if (IsFlagSet(cfCall, curPos)) - spRestored = true; // acts like mov esp, ebp - - sp = -1; - SetFlags(cfFrame, curPos, instrLen); - // ret - stop analyze output regs - lastCallAdr = 0; - firstPopRegIdx = -1; - popBytes = 0; - // define all pop registers (ret skipped) - for (Pos = curPos - 1; Pos >= fromPos; Pos--) { - b = Flags[Pos]; - if (b & cfInstruction) { - // pop instruction - if (b & cfPop) { - // pop ecx - if (b & cfSkip) - break; - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); - firstPopRegIdx = DisInfo1.OpRegIdx[0]; - popBytes += 4; - SetFlags(cfFrame, Pos, instrLen1); - } - else { - // skip frame instruction - if (b & cfFrame) - continue; - // set eax - function - if (b & cfSetA) { - recN1 = GetInfoRec(fromAdr); - recN1->procInfo->flags |= PF_OUTEAX; - if (!kb && !(recN1->procInfo->flags & (PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->kind = ikFunc; - Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); - op = Disasm.GetOp(DisInfo1.Mnem); - // if setXX - return type is Boolean - if (op == OP_SET) - recN1->type = "Boolean"; - } - } - break; - } - } - } - } - if (firstPopRegIdx != -1) { - // Skip pushed regs - if (spRestored) { - for (Pos = fromPos; ; Pos++) { - b = Flags[Pos]; - // Proc end - // if (Pos != fromPos && (b & cfProcEnd)) - if (_procSize && Pos - fromPos + 1 >= _procSize) - break; - if (b & cfInstruction) { - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); - SetFlags(cfFrame, Pos, instrLen1); - if ((b & cfPush) && (DisInfo1.OpRegIdx[0] == firstPopRegIdx)) - break; - } - } - } - else { - for (Pos = fromPos; ; Pos++) { - if (!popBytes) - break; - - b = Flags[Pos]; - // End of proc - // if (Pos != fromPos && (b & cfProcEnd)) - if (_procSize && Pos - fromPos + 1 >= _procSize) - break; - if (b & cfInstruction) { - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); - op = Disasm.GetOp(DisInfo1.Mnem); - SetFlags(cfFrame, Pos, instrLen1); - // add esp,... - if (op == OP_ADD && DisInfo1.OpRegIdx[0] == 20) { - popBytes += (int)DisInfo1.Immediate; - continue; - } - // sub esp,... - if (op == OP_SUB && DisInfo1.OpRegIdx[0] == 20) { - popBytes -= (int)DisInfo1.Immediate; - continue; - } - if (b & cfPush) - popBytes -= 4; - } - } - } - } - // If no prototype, try add information from analyze arguments result - if (!recN->HasName() && className != "") { - // dynamic - if (recN->procInfo->flags & PF_DYNAMIC) { - } - else { - } - } - if (!kb) { - if (inA) { - if (className != "") - recN->procInfo->AddArg(0x21, 0, 4, "Self", className); - else - recN->procInfo->AddArg(0x21, 0, 4, "", ""); - } - if (inD) { - if (recN->kind == ikConstructor || recN->kind == ikDestructor) - recN->procInfo->AddArg(0x21, 1, 4, "_Dv__", "Boolean"); - else - recN->procInfo->AddArg(0x21, 1, 4, "", ""); - } - if (inC) { - recN->procInfo->AddArg(0x21, 2, 4, "", ""); - } - } - break; - } - if (!IsFlagSet(cfSkip, curPos)) - sp = -1; - } - - if (op == OP_MOV) { - lastMovAdr = DisInfo.Offset; - lastMovImm = DisInfo.Immediate; - } - // init stack via loop - if (IsFlagSet(cfLoc, curPos)) { - recN1 = GetInfoRec(curAdr); - if (recN1 && recN1->xrefs && recN1->xrefs->Count == 1) { - PXrefRec recX = (PXrefRec)recN1->xrefs->Items[0]; - Adr = recX->adr + recX->offset; - if (Adr > curAdr) { - sSize = IsInitStackViaLoop(curAdr, Adr); - if (sSize) { - procStackSize += sSize * lastMovImm; - // skip jne - instrLen = Disasm.Disassemble(Code + Adr2Pos(Adr), (__int64)Adr, 0, 0); - curAdr = Adr + instrLen; - curPos = Adr2Pos(curAdr); - SetFlags(cfFrame, fromPos, curAdr - fromAdr); - continue; - } - } - } - } - // add (sub) esp,... - if (DisInfo.OpRegIdx[0] == 20 && DisInfo.OpType[1] == otIMM) { - if (op == OP_ADD) { - if ((int)DisInfo.Immediate < 0) - procStackSize -= (int)DisInfo.Immediate; - } - if (op == OP_SUB) { - if ((int)DisInfo.Immediate > 0) - procStackSize += (int)DisInfo.Immediate; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - /* - //dec reg - if (op == OP_DEC && DisInfo.Op1Type == otREG) - { - //Save (dec reg) address - Adr = curAdr; - //Look next instruction - curPos += instrLen; - curAdr += instrLen; - instrLen = Disasm.Disassemble(Code + curPos, (__int64)curAdr, &DisInfo1, 0); - //If jne @1, where @1 < adr of jne, when make frame from begin if Stack inited via loop - if (DisInfo1.Conditional && DisInfo1.Immediate < curAdr && DisInfo1.Immediate >= fromAdr) - { - if (IsInitStackViaLoop(DisInfo1.Immediate, Adr)) - SetFlags(cfFrame, fromPos, curPos + instrLen - fromPos + 1); - } - continue; - } - */ - - // mov esp, ebp - if (b1 == 0x8B && b2 == 0xE5) - spRestored = true; - - if (!IsFlagSet(cfSkip, curPos)) { - if (IsFlagSet(cfPush, curPos)) { - if (curPos != fromPos && sp < 255) { - sp++; - stack[sp] = curPos; - } - } - if (IsFlagSet(cfPop, curPos) && sp >= 0) { - macroFrom = stack[sp]; - SetFlag(cfBracket, macroFrom); - macroTo = curPos; - SetFlag(cfBracket, macroTo); - sp--; - } - } - - if (b1 == 0xFF && (b2 & 0x38) == 0x20 && DisInfo.OpType[0] == otMEM && IsValidImageAdr(DisInfo.Offset)) // near absolute indirect jmp (Case) - { - if (!IsValidCodeAdr(DisInfo.Offset)) - break; - DWORD cTblAdr = 0, jTblAdr = 0; - - Pos = curPos + instrLen; - Adr = curAdr + instrLen; - // Taqble address - last 4 bytes of instruction - jTblAdr = *((DWORD*)(Code + Pos - 4)); - // Analyze gap to find table cTbl - if (Adr <= lastMovAdr && lastMovAdr < jTblAdr) - cTblAdr = lastMovAdr; - // If cTblAdr exists, skip it - BYTE CTab[256]; - if (cTblAdr) { - int CNum = jTblAdr - cTblAdr; - Pos += CNum; - Adr += CNum; - } - for (int k = 0; k < 4096; k++) { - // Loc - end of table - if (IsFlagSet(cfLoc, Pos)) - break; - - Adr1 = *((DWORD*)(Code + Pos)); - // Validate Adr1 - if (!IsValidCodeAdr(Adr1) || Adr1 < fromAdr) - break; - // Set cfLoc - SetFlag(cfLoc, Adr2Pos(Adr1)); - - Pos += 4; - Adr += 4; - if (Adr1 > lastAdr) - lastAdr = Adr1; - } - if (Adr > lastAdr) - lastAdr = Adr; - curPos = Pos; - curAdr = Adr; - continue; - } - // ---------------------------------- - // PosTry: xor reg, reg - // push ebp - // push offset @1 - // push fs:[reg] - // mov fs:[reg], esp - // ... - // @2: ... - // At @1 we have various situations: - // ---------------------------------- - // @1: jmp @HandleFinally - // jmp @2 - // ---------------------------------- - // @1: jmp @HandleAnyException - // call DoneExcept - // ---------------------------------- - // @1: jmp HandleOnException - // dd num - // Follow the table of num records like: - // dd offset ExceptionInfo - // dd offset ExceptionProc - // ---------------------------------- - if (b1 == 0x68) // try block (push loc_TryBeg) - { - DWORD NPos = curPos + instrLen; - // check that next instruction is push fs:[reg] or retn - if ((Code[NPos] == 0x64 && Code[NPos + 1] == 0xFF && ((Code[NPos + 2] >= 0x30 && Code[NPos + 2] <= 0x37) || Code[NPos + 2] == 0x75)) || Code[NPos] == 0xC3) { - Adr = DisInfo.Immediate; // Adr=@1 - if (IsValidCodeAdr(Adr)) { - if (Adr > lastAdr) - lastAdr = Adr; - Pos = Adr2Pos(Adr); - if (Pos >= 0 && Pos - NPos < MAX_DISASSEMBLE) { - if (Code[Pos] == 0xE9) // jmp Handle... - { - // Disassemble jmp - instrLen1 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - - recN1 = GetInfoRec(DisInfo.Immediate); - if (recN1) { - if (recN1->SameName("@HandleFinally")) { - // ret + jmp HandleFinally - Pos += instrLen1; - Adr += instrLen1; - // jmp @2 - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN1->SameName("@HandleAnyException") || recN1->SameName("@HandleAutoException")) { - // jmp HandleAnyException - Pos += instrLen1; - Adr += instrLen1; - // call DoneExcept - instrLen2 = Disasm.Disassemble(Code + Pos, (__int64)Adr, 0, 0); - Adr += instrLen2; - if (Adr > lastAdr) - lastAdr = Adr; - } - else if (recN1->SameName("@HandleOnException")) { - // jmp HandleOnException - Pos += instrLen1; - Adr += instrLen1; - // dd num - num = *((int*)(Code + Pos)); - Pos += 4; - if (Adr + 4 + 8 * num > lastAdr) - lastAdr = Adr + 4 + 8 * num; - - for (int k = 0; k < num; k++) { - // dd offset ExceptionInfo - Pos += 4; - // dd offset ExceptionProc - Pos += 4; - } - } - } - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - } - while (1) { - // Call - stop analyze of arguments - if (DisInfo.Call) { - lastemb = false; - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - recN1 = GetInfoRec(Adr); - if (recN1 && recN1->procInfo) { - lastemb = (recN1->procInfo->flags & PF_EMBED); - WORD retb; - // @XStrCatN - if (recN1->SameName("@LStrCatN") || recN1->SameName("@WStrCatN") || recN1->SameName("@UStrCatN") || recN1->SameName("Format")) { - retb = 0; - } - else - retb = recN1->procInfo->retBytes; - - if (retb && sp >= retb) - sp -= retb; - else - sp = -1; - } - else - sp = -1; - // call not always preserve registers eax, edx, ecx - if (recN1) { - // @IntOver, @BoundErr nothing change - if (!recN1->SameName("@IntOver") && !recN1->SameName("@BoundErr")) { - argA = argD = argC = false; - } - } - else { - argA = argD = argC = false; - } - } - else { - argA = argD = argC = false; - sp = -1; - } - break; - } - // jmp - stop analyze of output arguments - if (op == OP_JMP) { - lastCallAdr = 0; - break; - } - // cop ..., [ebp + Offset] - if (!kb && bpBased && DisInfo.BaseReg == 21 && DisInfo.IndxReg == -1 && (int)DisInfo.Offset > 0) { - recN1 = GetInfoRec(fromAdr); - // For embedded procs we have on1 additional argument (pushed on stack first), that poped from stack by instrcution pop ecx - if (!emb || (int)DisInfo.Offset != retBytes + bpBase) { - int argSize = DisInfo.OpSize; - String argType = ""; - if (argSize == 10) - argType = "Extended"; - // Each argument in stack has size 4*N bytes - if (argSize < 4) - argSize = 4; - argSize = ((argSize + 3) / 4) * 4; - recN1->procInfo->AddArg(0x21, (int)DisInfo.Offset, argSize, "", argType); - } - } - // Instruction pop reg always change reg - if (op == OP_POP && DisInfo.OpType[0] == otREG) { - // eax - if (DisInfo.OpRegIdx[0] == 16) { - // Forget last call and set flag cfSkip, if it was call of embedded proc - if (lastCallAdr) { - if (lastemb) { - SetFlag(cfSkip, curPos); - lastemb = false; - } - lastCallAdr = 0; - } - - if (argA && !inA) { - argA = false; - if (!inD) - argD = false; - if (!inC) - argC = false; - } - } - // edx - if (DisInfo.OpRegIdx[0] == 18) { - if (argD && !inD) { - argD = false; - if (!inC) - argC = false; - } - } - // ecx - if (DisInfo.OpRegIdx[0] == 17) { - if (argC && !inC) - argC = false; - } - break; - } - // cdq always change edx; eax may be output argument of last call - if (op == OP_CDQ) { - if (lastCallAdr) { - recN1 = GetInfoRec(lastCallAdr); - if (recN1 && recN1->procInfo && !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->procInfo->flags |= PF_OUTEAX; - recN1->kind = ikFunc; - } - lastCallAdr = 0; - } - if (argD && !inD) { - argD = false; - if (!inC) - argC = false; - } - break; - } - if (DisInfo.Float) { - // fstsw, fnstsw always change eax - if (!memcmp(DisInfo.Mnem + 1, "stsw", 4) || !memcmp(DisInfo.Mnem + 1, "nstsw", 5)) { - if (DisInfo.OpType[0] == otREG && (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0)) { - if (lastCallAdr) - lastCallAdr = 0; - - if (argA && !inA) { - argA = false; - if (!inD) - argD = false; - if (!inC) - argC = false; - } - } - SetFlags(cfSkip, curPos, instrLen); - break; - } - // Instructions fst, fstp after call means that it was call of function - if (!memcmp(DisInfo.Mnem + 1, "st", 2)) { - Pos = GetNearestUpInstruction(curPos, fromPos, 1); - if (Pos != -1 && IsFlagSet(cfCall, Pos)) { - if (lastCallAdr) { - recN1 = GetInfoRec(lastCallAdr); - if (recN1 && recN1->procInfo && !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->procInfo->flags |= PF_OUTEAX; - recN1->kind = ikFunc; - } - lastCallAdr = 0; - } - } - break; - } - } - // mul, div ????????????????????????????????????????????????????????????????????? - // xor reg, reg always change register - if (op == OP_XOR && DisInfo.OpType[0] == DisInfo.OpType[1] && DisInfo.OpRegIdx[0] == DisInfo.OpRegIdx[1]) { - if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) { - if (lastCallAdr) - lastCallAdr = 0; - } - if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) { - if (lastCallAdr) - lastCallAdr = 0; - } - - // eax, ax, ah, al - if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) { - SetFlag(cfSetA, curPos); - if (argA && !inA) { - argA = false; - if (!inD) - argD = false; - if (!inC) - argC = false; - } - } - // edx, dx, dh, dl - if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) { - SetFlag(cfSetD, curPos); - if (argD && !inD) { - argD = false; - if (!inC) - argC = false; - } - } - // ecx, cx, ch, cl - if (DisInfo.OpRegIdx[0] == 17 || DisInfo.OpRegIdx[0] == 9 || DisInfo.OpRegIdx[0] == 5 || DisInfo.OpRegIdx[0] == 1) { - SetFlag(cfSetC, curPos); - if (argC && !inC) - argC = false; - } - break; - } - // If eax, edx, ecx in memory address - always used as registers - if (DisInfo.BaseReg != -1 || DisInfo.IndxReg != -1) { - if (DisInfo.BaseReg == 16 || DisInfo.IndxReg == 16) { - if (lastCallAdr) { - recN1 = GetInfoRec(lastCallAdr); - if (recN1 && recN1->procInfo && !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->procInfo->flags |= PF_OUTEAX; - recN1->kind = ikFunc; - } - lastCallAdr = 0; - } - } - if (DisInfo.BaseReg == 16 || DisInfo.IndxReg == 16) { - if (argA && !inA) { - inA = true; - argA = false; - } - } - if (DisInfo.BaseReg == 18 || DisInfo.IndxReg == 18) { - if (argD && !inD) { - inD = true; - argD = false; - if (!inA) { - inA = true; - argA = false; - } - } - } - if (DisInfo.BaseReg == 17 || DisInfo.IndxReg == 17) { - if (argC && !inC) { - inC = true; - argC = false; - if (!inA) { - inA = true; - argA = false; - } - if (!inD) { - inD = true; - argD = false; - } - } - } - } - // xchg - if (op == OP_XCHG) { - if (DisInfo.OpType[0] == otREG) { - if (DisInfo.OpRegIdx[0] == 16) // eax - { - if (lastCallAdr) { - recN1 = GetInfoRec(lastCallAdr); - if (recN1 && recN1->procInfo && !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->procInfo->flags |= PF_OUTEAX; - recN1->kind = ikFunc; - } - lastCallAdr = 0; - } - } - if (DisInfo.OpRegIdx[0] == 16) // eax - { - SetFlag(cfSetA, curPos); - if (argA && !inA) { - inA = true; - argA = false; - } - } - if (DisInfo.OpRegIdx[0] == 18) // edx - { - SetFlag(cfSetD, curPos); - if (argD && !inD) { - inD = true; - argD = false; - if (!inA) { - inA = true; - argA = false; - } - } - } - if (DisInfo.OpRegIdx[0] == 17) // ecx - { - SetFlag(cfSetC, curPos); - // xchg ecx, [ebp...] - ecx used as argument - if (DisInfo.BaseReg == 21) { - inC = true; - argC = false; - if (!inA) { - inA = true; - argA = false; - } - if (!inD) { - inD = true; - argD = false; - } - // Set cfFrame upto start of procedure - SetFlags(cfFrame, fromPos, (curPos + instrLen - fromPos)); - } - else if (argC && !inC) { - inC = true; - argC = false; - if (!inA) { - inA = true; - argA = false; - } - if (!inD) { - inD = true; - argD = false; - } - } - } - } - if (DisInfo.OpType[1] == otREG) { - if (DisInfo.OpRegIdx[1] == 16) { - if (lastCallAdr) { - recN1 = GetInfoRec(lastCallAdr); - if (recN1 && recN1->procInfo && !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->procInfo->flags |= PF_OUTEAX; - recN1->kind = ikFunc; - } - lastCallAdr = 0; - } - } - if (DisInfo.OpRegIdx[1] == 16) { - SetFlag(cfSetA, curPos); - if (argA && !inA) { - inA = true; - argA = false; - } - } - if (DisInfo.OpRegIdx[1] == 18) { - SetFlag(cfSetD, curPos); - if (argD && !inD) { - inD = true; - argD = false; - if (!inA) { - inA = true; - argA = false; - } - } - } - if (DisInfo.OpRegIdx[1] == 17) { - SetFlag(cfSetC, curPos); - if (argC && !inC) { - inC = true; - argC = false; - if (!inA) { - inA = true; - argA = false; - } - if (!inD) { - inD = true; - argD = false; - } - } - } - } - break; - } - // cop ..., reg - if (DisInfo.OpType[1] == otREG) { - if (DisInfo.OpRegIdx[1] == 16 || DisInfo.OpRegIdx[1] == 8 || DisInfo.OpRegIdx[1] == 0) { - if (lastCallAdr) { - recN1 = GetInfoRec(lastCallAdr); - if (recN1 && recN1->procInfo && !(recN1->procInfo->flags & (PF_KBPROTO | PF_EVENT | PF_DYNAMIC)) && recN1->kind != ikConstructor && recN1->kind != ikDestructor) { - recN1->procInfo->flags |= PF_OUTEAX; - recN1->kind = ikFunc; - } - lastCallAdr = 0; - } - } - // eax, ax, ah, al - if (DisInfo.OpRegIdx[1] == 16 || DisInfo.OpRegIdx[1] == 8 || DisInfo.OpRegIdx[1] == 4 || DisInfo.OpRegIdx[1] == 0) { - if (argA && !inA) { - inA = true; - argA = false; - } - } - // edx, dx, dh, dl - if (DisInfo.OpRegIdx[1] == 18 || DisInfo.OpRegIdx[1] == 10 || DisInfo.OpRegIdx[1] == 6 || DisInfo.OpRegIdx[1] == 2) { - if (argD && !inD) { - inD = true; - argD = false; - if (!inA) { - inA = true; - argA = false; - } - } - } - // ecx, cx, ch, cl - if (DisInfo.OpRegIdx[1] == 17 || DisInfo.OpRegIdx[1] == 9 || DisInfo.OpRegIdx[1] == 5 || DisInfo.OpRegIdx[1] == 1) { - if (argC && !inC) { - inC = true; - argC = false; - if (!inA) { - inA = true; - argA = false; - } - if (!inD) { - inD = true; - argD = false; - } - } - } - } - - if (DisInfo.OpType[0] == otREG && op != OP_UNK && op != OP_PUSH) { - if (op != OP_MOV && op != OP_LEA && op != OP_SET) { - // eax, ax, ah, al - if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) { - if (argA && !inA) { - inA = true; - argA = false; - } - } - // edx, dx, dh, dl - if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) { - if (argD && !inD) { - inD = true; - argD = false; - if (!inA) { - inA = true; - argA = false; - } - } - } - // ecx, cx, ch, cl - if (DisInfo.OpRegIdx[0] == 17 || DisInfo.OpRegIdx[0] == 9 || DisInfo.OpRegIdx[0] == 5 || DisInfo.OpRegIdx[0] == 1) { - if (argC && !inC) { - inC = true; - argC = false; - if (!inA) { - inA = true; - argA = false; - } - if (!inD) { - inD = true; - argD = false; - } - } - } - } - else { - // eax, ax, ah, al - if (DisInfo.OpRegIdx[0] == 16 || DisInfo.OpRegIdx[0] == 8 || DisInfo.OpRegIdx[0] == 4 || DisInfo.OpRegIdx[0] == 0) { - SetFlag(cfSetA, curPos); - if (argA && !inA) { - argA = false; - if (!inD) - argD = false; - if (!inC) - argC = false; - } - if (lastCallAdr) - lastCallAdr = 0; - } - // edx, dx, dh, dl - if (DisInfo.OpRegIdx[0] == 18 || DisInfo.OpRegIdx[0] == 10 || DisInfo.OpRegIdx[0] == 6 || DisInfo.OpRegIdx[0] == 2) { - SetFlag(cfSetD, curPos); - if (argD && !inD) { - argD = false; - if (!inC) - argC = false; - } - if (lastCallAdr) - lastCallAdr = 0; - } - // ecx, cx, ch, cl - if (DisInfo.OpRegIdx[0] == 17 || DisInfo.OpRegIdx[0] == 9 || DisInfo.OpRegIdx[0] == 5 || DisInfo.OpRegIdx[0] == 1) { - SetFlag(cfSetC, curPos); - if (argC && !inC) - argC = false; - } - } - } - break; - } - - if (DisInfo.Call) // call sub_XXXXXXXX - { - lastCallAdr = 0; - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - retType = AnalyzeArguments(Adr); - lastCallAdr = Adr; - - recN1 = GetInfoRec(Adr); - if (recN1 && recN1->HasName()) { - // Hide some procedures - // @Halt0 is not executed - if (recN1->SameName("@Halt0")) { - SetFlags(cfSkip, curPos, instrLen); - if (fromAdr == EP && !lastAdr) - break; - } - // Procs together previous unstruction - else if (recN1->SameName("@IntOver") || recN1->SameName("@InitImports") || recN1->SameName("@InitResStringImports")) { - Pos = GetNearestUpInstruction(curPos, fromPos, 1); - if (Pos != -1) - SetFlags(cfSkip, Pos, (curPos - Pos) + instrLen); - } - // @BoundErr - else if (recN1->SameName("@BoundErr")) { - if (IsFlagSet(cfLoc, curPos)) { - Pos = GetNearestUpInstruction(curPos, fromPos, 1); - Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); - if (DisInfo1.Branch) { - Pos = GetNearestUpInstruction(Pos, fromPos, 3); - SetFlags(cfSkip, Pos, (curPos - Pos) + instrLen); - } - } - else { - Pos = GetNearestUpInstruction(curPos, fromPos, 1); - Disasm.Disassemble(Code + Pos, (__int64)Pos2Adr(Pos), &DisInfo1, 0); - if (DisInfo1.Branch) { - Pos = GetNearestUpInstruction(Pos, fromPos, 1); - if (IsFlagSet(cfPop, Pos)) { - Pos = GetNearestUpInstruction(Pos, fromPos, 3); - } - SetFlags(cfSkip, Pos, (curPos - Pos) + instrLen); - } - } - } - // Not in source code - else if (recN1->SameName("@_IOTest") || recN1->SameName("@InitExe") || recN1->SameName("@InitLib") || recN1->SameName("@DoneExcept")) { - SetFlags(cfSkip, curPos, instrLen); - } - } - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - - if (b1 == 0xEB || // short relative abs jmp or cond jmp - (b1 >= 0x70 && b1 <= 0x7F) || (b1 == 0xF && b2 >= 0x80 && b2 <= 0x8F)) { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - if (Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - if (b1 == 0xE9) // relative abs jmp or cond jmp - { - Adr = DisInfo.Immediate; - if (IsValidCodeAdr(Adr)) { - recN1 = GetInfoRec(Adr); - if (!recN1 && Adr >= fromAdr && Adr > lastAdr) - lastAdr = Adr; - } - curPos += instrLen; - curAdr += instrLen; - continue; - } - curPos += instrLen; - curAdr += instrLen; - } - // Check matching ret bytes and summary size of stack arguments - if (bpBased) { - if (recN->procInfo->args) { - int delta = retBytes; - for (int n = 0; n < recN->procInfo->args->Count; n++) { - argInfo = (PARGINFO)recN->procInfo->args->Items[n]; - if (argInfo->Ndx > 2) - delta -= argInfo->Size; - } - if (delta < 0) { - // If delta between N bytes (in "ret N" instruction) and total size of argumnets != 0 - recN->procInfo->flags |= PF_ARGSIZEG; - // delta = 4 and proc can be embbedded - allow that it really embedded - if (delta == 4 && (recN->procInfo->flags & PF_MAYBEEMBED)) { - // Ñòàâèì ôëàæîê PF_EMBED - recN->procInfo->flags |= PF_EMBED; - // Skip following after call instrcution "pop ecx" - for (int n = 0; n < recN->xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; - if (recX->type == 'C') { - Adr = recX->adr + recX->offset; - Pos = Adr2Pos(Adr); - instrLen = Disasm.Disassemble(Code + Pos, (__int64)Adr, &DisInfo, 0); - Pos += instrLen; - if (Code[Pos] == 0x59) - SetFlag(cfSkip, Pos); - } - } - } - } - // If delta < 0, then part of arguments can be unusable - else if (delta < 0) { - recN->procInfo->flags |= PF_ARGSIZEL; - } - } - } - recN = GetInfoRec(fromAdr); - // if PF_OUTEAX not set - Procedure - if (!kb && !(recN->procInfo->flags & PF_OUTEAX)) { - if (recN->kind != ikConstructor && recN->kind != ikDestructor) { - recN->kind = ikProc; - } - } - - recN->procInfo->stackSize = procStackSize + 0x1000; - if (lastCallAdr) - return retType; - return ""; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/Main.h b/Sources/Forms/Main.h deleted file mode 100644 index e56d48c..0000000 --- a/Sources/Forms/Main.h +++ /dev/null @@ -1,881 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef MainH -#define MainH -// --------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Disasm.h" -#include "KnowledgeBase.h" -#include "Resources.h" -#include "Infos.h" -#include "UFileDropper.h" - -#include "PEHeader.h" -// --------------------------------------------------------------------------- -#define USER_KNOWLEDGEBASE 0x80000000 -#define SOURCE_LIBRARY 0x40000000 -#define WM_UPDANALYSISSTATUS WM_USER + 100 -#define WM_DFMCLOSED WM_USER + 101 -#define DELHPI_VERSION_AUTO 0 -// --------------------------------------------------------------------------- -// Internal unit types -#define drStop 0 -#define drStop_a 0x61 //'a' - Last Tag in all files -#define drStop1 0x63 //'c' -#define drUnit 0x64 //'d' -#define drUnit1 0x65 //'e' - in implementation -#define drImpType 0x66 //'f' -#define drImpVal 0x67 //'g' -#define drDLL 0x68 //'h' -#define drExport 0x69 //'i' -#define drEmbeddedProcStart 0x6A //'j' -#define drEmbeddedProcEnd 0x6B //'k' -#define drCBlock 0x6C //'l' -#define drFixUp 0x6D //'m' -#define drImpTypeDef 0x6E //'n' - import of type definition by "A = type B" -#define drUnit2 0x6F //'o' - ??? for D2010 -#define drSrc 0x70 //'p' -#define drObj 0x71 //'q' -#define drRes 0x72 //'r' -#define drAsm 0x73 //'s' - Found in D5 Debug versions -#define drStop2 0x9F //'_' -#define drConst 0x25 //'%' -#define drResStr 0x32 //'2' -#define drType 0x2A //'*' -#define drTypeP 0x26 //'&' -#define drProc 0x28 //'(' -#define drSysProc 0x29 //')' -#define drVoid 0x40 //'@' -#define drVar 0x20 //' ' -#define drThreadVar 0x31 //'1' -#define drVarC 0x27 //''' -#define drBoolRangeDef 0x41 //'A' -#define drChRangeDef 0x42 //'B' -#define drEnumDef 0x43 //'C' -#define drRangeDef 0x44 //'D' -#define drPtrDef 0x45 //'E' -#define drClassDef 0x46 //'F' -#define drObjVMTDef 0x47 //'G' -#define drProcTypeDef 0x48 //'H' -#define drFloatDef 0x49 //'I' -#define drSetDef 0x4A //'J' -#define drShortStrDef 0x4B //'K' -#define drArrayDef 0x4C //'L' -#define drRecDef 0x4D //'M' -#define drObjDef 0x4E //'N' -#define drFileDef 0x4F //'O' -#define drTextDef 0x50 //'P' -#define drWCharRangeDef 0x51 //'Q' - WideChar -#define drStringDef 0x52 //'R' -#define drVariantDef 0x53 //'S' -#define drInterfaceDef 0x54 //'T' -#define drWideStrDef 0x55 //'U' -#define drWideRangeDef 0x56 //'V' -// --------------------------------------------------------------------------- -typedef struct { - DWORD Start; - DWORD Size; - DWORD Flags; - String Name; -} SegmentInfo, *PSegmentInfo; - -/* - typedef struct - { - DWORD dwRVAFunctionNameList; - DWORD dwUseless1; - DWORD dwUseless2; - DWORD dwRVAModuleName; - DWORD dwRVAFunctionAddressList; - } IMAGE_IMPORT_DIRECTORY; - */ -#define cfUndef 0x00000000 -#define cfCode 0x00000001 -#define cfData 0x00000002 -#define cfImport 0x00000004 -#define cfCall 0x00000008 -#define cfProcStart 0x00000010 -#define cfProcEnd 0x00000020 -#define cfRTTI 0x00000040 -#define cfEmbedded 0x00000080 //Calls in range of one proc (for ex. calls in FormatBuf) -#define cfPass0 0x00000100 //Initial Analyze was done -#define cfFrame 0x00000200 -#define cfSwitch 0x00000400 -#define cfPass1 0x00000800 //Analyze1 was done -#define cfETable 0x00001000 //Exception Table -#define cfPush 0x00002000 -#define cfDSkip 0x00004000 //For Decompiler -#define cfPop 0x00008000 -#define cfSetA 0x00010000 //eax setting -#define cfSetD 0x00020000 //edx setting -#define cfSetC 0x00040000 //ecx setting -#define cfBracket 0x00080000 //Bracket (ariphmetic operation) -#define cfPass2 0x00100000 //Analyze2 was done -#define cfExport 0x00200000 -#define cfPass 0x00400000 //Pass Flag (for AnalyzeArguments and Decompiler) -#define cfLoc 0x00800000 //Loc_ position -#define cfTry 0x01000000 -#define cfFinally 0x02000000 -#define cfExcept 0x04000000 -#define cfLoop 0x08000000 -#define cfFinallyExit 0x10000000 //Exit section (from try...finally construction) -#define cfVTable 0x20000000 //Flags for Interface entries (to mark start end finish of VTables) -#define cfSkip 0x40000000 -#define cfInstruction 0x80000000 //Instruction begin - -typedef struct { - String name; - DWORD codeOfs; - int codeLen; -} FuncListRec, *PFuncListRec; - -typedef struct UnitRec { - ~UnitRec() { - delete names; - } - - bool trivial; // Trivial unit - bool trivialIni; // Initialization procedure is trivial - bool trivialFin; // Finalization procedure is trivial - bool kb; // Unit is in knowledge base - int fromAdr; // From Address - int toAdr; // To Address - int finadr; // Finalization procedure address - int finSize; // Finalization procedure size - int iniadr; // Initialization procedure address - int iniSize; // Initialization procedure size - float matchedPercent; // Matching procent of code in unit - int iniOrder; // Initialization procs order - TStringList *names; // Possible names list -} UnitRec, *PUnitRec; - -typedef struct { - BYTE kind; - DWORD adr; - String name; -} TypeRec, *PTypeRec; - -typedef struct { - int height; - DWORD vmtAdr; - String vmtName; -} VmtListRec, *PVmtListRec; - -// Delphi2 -// (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, -// tkClass, tkMethod, tkWChar, tkLString, tkLWString, tkVariant) - -#define ikUnknown 0x00 //UserDefined! -#define ikInteger 0x01 -#define ikChar 0x02 -#define ikEnumeration 0x03 -#define ikFloat 0x04 -#define ikString 0x05 //ShortString -#define ikSet 0x06 -#define ikClass 0x07 -#define ikMethod 0x08 -#define ikWChar 0x09 -#define ikLString 0x0A //String, AnsiString -#define ikWString 0x0B //WideString -#define ikVariant 0x0C -#define ikArray 0x0D -#define ikRecord 0x0E -#define ikInterface 0x0F -#define ikInt64 0x10 -#define ikDynArray 0x11 -// >=2009 -#define ikUString 0x12 //UnicodeString -// >=2010 -#define ikClassRef 0x13 -#define ikPointer 0x14 -#define ikProcedure 0x15 - -// Äîïîëíèòåëüíûå òèïû -#define ikCString 0x20 //PChar, PAnsiChar -#define ikWCString 0x21 //PWideChar - -#define ikResString 0x22 -#define ikVMT 0x23 //VMT -#define ikGUID 0x24 -#define ikRefine 0x25 //Code, but what - procedure or function? -#define ikConstructor 0x26 -#define ikDestructor 0x27 -#define ikProc 0x28 -#define ikFunc 0x29 - -#define ikLoc 0x2A -#define ikData 0x2B -#define ikDataLink 0x2C //Link to variable from other module -#define ikExceptName 0x2D -#define ikExceptHandler 0x2E -#define ikExceptCase 0x2F -#define ikSwitch 0x30 -#define ikCase 0x31 -#define ikFixup 0x32 //Fixup (for example, TlsLast) -#define ikThreadVar 0x33 -#define ikTry 0x34 //!!!Deleted - old format!!! - -enum NameVersion { - nvPrimary, nvAfterScan, nvByUser -}; -// XRef Type -#define XREF_UNKNOWN 0x20 //Black -#define XREF_CALL 1 //Blue -#define XREF_JUMP 2 //Green -#define XREF_CONST 3 //Light red - -typedef struct { - String name; - DWORD address; - WORD ord; -} ExportNameRec, *PExportNameRec; - -typedef struct { - String module; - String name; - DWORD address; -} ImportNameRec, *PImportNameRec; - -enum OrdType { - OtSByte, OtUByte, OtSWord, OtUWord, OtSLong, OtULong -}; - -enum FloatType { - FtSingle, FtDouble, FtExtended, FtComp, FtCurr -}; - -enum MethodKind { - MkProcedure, MkFunction, MkConstructor, MkDestructor, MkClassProcedure, MkClassFunction -}; - -#define PfVar 0x1 -#define PfConst 0x2 -#define PfArray 0x4 -#define PfAddress 0x8 -#define PfReference 0x10 -#define PfOut 0x20 - -enum IntfFlag { - IfHasGuid, IfDispInterface, IfDispatch -}; - -// Proc navigation history record -typedef struct { - DWORD adr; // Procedure Address - int itemIdx; // Selected Item Index - int xrefIdx; // Selected Xref Index - int topIdx; // TopIndex of ListBox -} PROCHISTORYREC, *PPROCHISTORYREC; -// --------------------------------------------------------------------------- -// Information about registry -typedef struct { - BYTE result; // 0 - nothing, 1 - type was set, 2 - type mismatch - char source; - // 0 - not defined; 'L' - local var; 'A' - argument; 'M' - memory; 'I' - immediate - DWORD value; - String type; -} RINFO, *PRINFO; -// --------------------------------------------------------------------------- -typedef struct { - char* name; - DWORD impAdr; -} SysProcInfo; -// --------------------------------------------------------------------------- -// Common -#define MAXLEN 100 -#define MAXLINE 1024 -#define MAXNAME 1024 -#define MAXSTRBUFFER 10000 -#define MAXBINTEMPLATE 1000 -#define MAX_DISASSEMBLE 250000 -#define MAX_ITEMS 0x10000 //Max items number for read-write -#define HISTORY_CHUNK_LENGTH 256 -// Search -#define SEARCH_UNITS 0 -#define SEARCH_UNITITEMS 1 -#define SEARCH_RTTIS 2 -#define SEARCH_CLASSVIEWER 3 -#define SEARCH_STRINGS 4 -#define SEARCH_FORMS 5 -#define SEARCH_CODEVIEWER 6 -#define SEARCH_NAMES 7 -#define SEARCH_SOURCEVIEWER 8 - -int DISX86Create(); -void DISX86Destroy(); - -// --------------------------------------------------------------------------- -template -void CleanupList(TList* list) { - if (list) { - for (int i = 0; i < list->Count; ++i) { - T* item = (T*)list->Items[i]; - delete item; - } - - delete list; - } -} -// --------------------------------------------------------------------------- -class TDfm; - -class TFMain_11011981 : public TForm { -__published: // IDE-managed Components - TMenuItem *miFile; - TMenuItem *miLoadFile; - TMenuItem *miExit; - TMenuItem *miSaveProject; - TOpenDialog *OpenDlg; - TMainMenu *MainMenu; - TMenuItem *miTools; - TPageControl *pcInfo; - TTabSheet *tsUnits; - TTabSheet *tsRTTIs; - TListBox *lbUnits; - TListBox *lbRTTIs; - TMenuItem *miOpenProject; - TPageControl *pcWorkArea; - TTabSheet *tsCodeView; - TListBox *lbCode; - TPopupMenu *pmCode; - TMenuItem *miGoTo; - TMenuItem *miExploreAdr; - TSaveDialog *SaveDlg; - TSplitter *SplitterH1; - TSplitter *SplitterV1; - TMenuItem *miViewProto; - TPanel *CodePanel; - TButton *bEP; - TButton *bCodePrev; - TTabSheet *tsClassView; - TTreeView *tvClassesFull; - TTabSheet *tsStrings; - TListBox *lbStrings; - TPanel *Panel1; - TPopupMenu *pmUnits; - TMenuItem *miSearchUnit; - TMenuItem *miSortUnits; - TMenuItem *miSortUnitsByAdr; - TMenuItem *miSortUnitsByOrd; - TPopupMenu *pmRTTIs; - TPopupMenu *pmVMTs; - TMenuItem *miSearchRTTI; - TMenuItem *miSortRTTI; - TMenuItem *miSortRTTIsByAdr; - TMenuItem *miSortRTTIsByKnd; - TMenuItem *miSortRTTIsByNam; - TMenuItem *miSearchVMT; - TMenuItem *miCopyCode; - TMenuItem *miRenameUnit; - TPopupMenu *pmUnitItems; - TMenuItem *miSearchItem; - TTabSheet *tsForms; - TPanel *Panel2; - TRadioGroup *rgViewFormAs; - TListBox *lbForms; - TMenuItem *miCollapseAll; - TListBox *lbCXrefs; - TPanel *ShowCXrefs; - TMenuItem *miSortUnitsByNam; - TTreeView *tvClassesShort; - TRadioGroup *rgViewerMode; - TMenuItem *miClassTreeBuilder; - TMenuItem *miMRF; - TMenuItem *miExe1; - TMenuItem *miExe2; - TMenuItem *miExe3; - TMenuItem *miExe4; - TMenuItem *miIdp1; - TMenuItem *miIdp2; - TMenuItem *miIdp3; - TMenuItem *miIdp4; - TMenuItem *N1; - TTabSheet *tsItems; - TStringGrid *sgItems; - TMenuItem *miExe5; - TMenuItem *miExe6; - TMenuItem *miExe7; - TMenuItem *miExe8; - TMenuItem *miIdp5; - TMenuItem *miIdp6; - TMenuItem *miIdp7; - TMenuItem *miIdp8; - TListBox *lbUnitItems; - TMenuItem *miEditFunctionC; - TMenuItem *miMapGenerator; - TMenuItem *miAutodetectVersion; - TMenuItem *miDelphi2; - TMenuItem *miDelphi3; - TMenuItem *miDelphi4; - TMenuItem *miDelphi5; - TMenuItem *miDelphi6; - TMenuItem *miDelphi7; - TMenuItem *miDelphi2006; - TMenuItem *miDelphi2007; - TMenuItem *miKBTypeInfo; - TMenuItem *miName; - TMenuItem *miLister; - TButton *bCodeNext; - TLabel *lProcName; - TMenuItem *miInformation; - TMenuItem *miEditFunctionI; - TPopupMenu *pmStrings; - TMenuItem *miSearchString; - TMenuItem *miViewClass; - TMenuItem *miDelphi2009; - TMenuItem *miDelphi2010; - TPanel *Panel3; - TListBox *lbSXrefs; - TPanel *ShowSXrefs; - TMenuItem *miAbout; - TMenuItem *miHelp; - TMenuItem *miEditClass; - TMenuItem *miCtdPassword; - TPopupMenu *pmCodePanel; - TMenuItem *miEmptyHistory; - TMenuItem *miTabs; - TMenuItem *Units1; - TMenuItem *RTTI1; - TMenuItem *Forms1; - TMenuItem *CodeViewer1; - TMenuItem *ClassViewer1; - TMenuItem *Strings1; - TMenuItem *miUnitDumper; - TTabSheet *tsNames; - TMenuItem *Names1; - TListBox *lbNames; - TPanel *Panel4; - TSplitter *Splitter1; - TListBox *lbAliases; - TPanel *pnlAliases; - TLabel *lClassName; - TComboBox *cbAliases; - TButton *bApplyAlias; - TButton *bCancelAlias; - TMenuItem *miLegend; - TMenuItem *miFuzzyScanKB; - TMenuItem *miCopyList; - TMenuItem *miDelphi2005; - TMenuItem *miCommentsGenerator; - TMenuItem *miIDCGenerator; - TMenuItem *miSaveDelphiProject; - TTabSheet *tsSourceCode; - TListBox *lbSourceCode; - TMenuItem *SourceCode1; - TPanel *Panel5; - TPanel *ShowNXrefs; - TListBox *lbNXrefs; - TMenuItem *miHex2Double; - TActionList *alMain; - TAction *acOnTop; - TAction *acShowBar; - TAction *acShowHoriz; - TAction *acDefCol; - TAction *acColorThis; - TAction *acFontAll; - TAction *acColorAll; - TFontDialog *FontsDlg; - TMenuItem *Appearance2; - TMenuItem *Colorsall2; - TMenuItem *Colorsthis2; - TMenuItem *Fontall2; - TMenuItem *Fontthis2; - TMenuItem *Defaultcolumns2; - TMenuItem *Showhorizontalscroll2; - TMenuItem *Showbar2; - TButton *bDecompile; - TMenuItem *miCopyStrings; - TMenuItem *miCopyAddressI; - TMenuItem *miCopyAddressCode; - TPopupMenu *pmSourceCode; - TMenuItem *miCopySource2Clipboard; - TMenuItem *miDelphiXE1; - TMenuItem *miXRefs; - TMenuItem *miDelphiXE2; - TMenuItem *miPlugins; - TMenuItem *miViewAll; - TCheckBox *cbMultipleSelection; - TMenuItem *miSwitchSkipFlag; - TMenuItem *miSwitchFrameFlag; - TMenuItem *miSwitchFlag; - TMenuItem *cfTry1; - TMenuItem *miDelphiXE3; - TMenuItem *miSettings; - TMenuItem *miacFontAll; - TMenuItem *miDelphiXE4; - TMenuItem *miProcessDumper; - TMenuItem *miSetlvartype; - - void __fastcall miExitClick(TObject *Sender); - void __fastcall miAutodetectVersionClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - void __fastcall FormDestroy(TObject *Sender); - void __fastcall miSaveProjectClick(TObject *Sender); - void __fastcall miOpenProjectClick(TObject *Sender); - void __fastcall lbCodeDblClick(TObject *Sender); - void __fastcall bEPClick(TObject *Sender); - void __fastcall lbStringsDblClick(TObject *Sender); - void __fastcall lbRTTIsDblClick(TObject *Sender); - void __fastcall lbUnitItemsDblClick(TObject *Sender); - void __fastcall lbUnitsDblClick(TObject *Sender); - void __fastcall miGoToClick(TObject *Sender); - void __fastcall miExploreAdrClick(TObject *Sender); - void __fastcall miNameClick(TObject *Sender); - void __fastcall miViewProtoClick(TObject *Sender); - void __fastcall lbXrefsDblClick(TObject *Sender); - void __fastcall bCodePrevClick(TObject *Sender); - void __fastcall tvClassesDblClick(TObject *Sender); - void __fastcall miSearchUnitClick(TObject *Sender); - void __fastcall miSortUnitsByAdrClick(TObject *Sender); - void __fastcall miSortUnitsByOrdClick(TObject *Sender); - void __fastcall miSearchVMTClick(TObject *Sender); - void __fastcall miSearchRTTIClick(TObject *Sender); - void __fastcall miSortRTTIsByAdrClick(TObject *Sender); - void __fastcall miSortRTTIsByKndClick(TObject *Sender); - void __fastcall miSortRTTIsByNamClick(TObject *Sender); - void __fastcall miCopyCodeClick(TObject *Sender); - void __fastcall miRenameUnitClick(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall lbFormsDblClick(TObject *Sender); - void __fastcall lbUnitsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State); - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall lbCodeKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall miCollapseAllClick(TObject *Sender); - void __fastcall NamePosition(); - void __fastcall GoToAddress(); - void __fastcall FindText(String Str); - void __fastcall miSearchItemClick(TObject *Sender); - void __fastcall ShowCXrefsClick(TObject *Sender); - void __fastcall lbUnitItemsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State); - void __fastcall lbUnitsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall lbRTTIsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall lbFormsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall lbCodeMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall tvClassesFullMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall lbStringsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall lbUnitItemsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall lbXrefsMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall miSortUnitsByNamClick(TObject *Sender); - void __fastcall rgViewerModeClick(TObject *Sender); - void __fastcall tvClassesShortMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall miClassTreeBuilderClick(TObject *Sender); - void __fastcall lbUnitsClick(TObject *Sender); - void __fastcall lbRTTIsClick(TObject *Sender); - void __fastcall lbUnitItemsClick(TObject *Sender); - void __fastcall tvClassesShortClick(TObject *Sender); - void __fastcall tvClassesFullClick(TObject *Sender); - void __fastcall miExe1Click(TObject *Sender); - void __fastcall miExe2Click(TObject *Sender); - void __fastcall miExe3Click(TObject *Sender); - void __fastcall miExe4Click(TObject *Sender); - void __fastcall miIdp1Click(TObject *Sender); - void __fastcall miIdp2Click(TObject *Sender); - void __fastcall miIdp3Click(TObject *Sender); - void __fastcall miIdp4Click(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall miKBTypeInfoClick(TObject *Sender); - void __fastcall miExe5Click(TObject *Sender); - void __fastcall miExe6Click(TObject *Sender); - void __fastcall miExe7Click(TObject *Sender); - void __fastcall miExe8Click(TObject *Sender); - void __fastcall miIdp5Click(TObject *Sender); - void __fastcall miIdp6Click(TObject *Sender); - void __fastcall miIdp7Click(TObject *Sender); - void __fastcall miIdp8Click(TObject *Sender); - void __fastcall FormResize(TObject *Sender); - void __fastcall miEditFunctionCClick(TObject *Sender); - void __fastcall lbXrefsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State); - void __fastcall miMapGeneratorClick(TObject *Sender); - void __fastcall pmUnitsPopup(TObject *Sender); - void __fastcall lbCodeDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State); - void __fastcall miDelphi2Click(TObject *Sender); - void __fastcall miDelphi3Click(TObject *Sender); - void __fastcall miDelphi4Click(TObject *Sender); - void __fastcall miDelphi5Click(TObject *Sender); - void __fastcall miDelphi6Click(TObject *Sender); - void __fastcall miDelphi7Click(TObject *Sender); - void __fastcall miDelphi2005Click(TObject *Sender); - void __fastcall miDelphi2006Click(TObject *Sender); - void __fastcall miDelphi2007Click(TObject *Sender); - void __fastcall lbXrefsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall lbUnitsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall lbRTTIsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall lbFormsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall tvClassesShortKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall lbUnitItemsKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall miListerClick(TObject *Sender); - void __fastcall bCodeNextClick(TObject *Sender); - void __fastcall miEditFunctionIClick(TObject *Sender); - void __fastcall miSearchStringClick(TObject *Sender); - void __fastcall lbStringsClick(TObject *Sender); - void __fastcall miViewClassClick(TObject *Sender); - void __fastcall pmVMTsPopup(TObject *Sender); - void __fastcall lbStringsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State); - void __fastcall ShowSXrefsClick(TObject *Sender); - void __fastcall miAboutClick(TObject *Sender); - void __fastcall miHelpClick(TObject *Sender); - void __fastcall pmRTTIsPopup(TObject *Sender); - void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); - void __fastcall miEditClassClick(TObject *Sender); - void __fastcall miCtdPasswordClick(TObject *Sender); - void __fastcall pmCodePanelPopup(TObject *Sender); - void __fastcall miEmptyHistoryClick(TObject *Sender); - void __fastcall pmStringsPopup(TObject *Sender); - void __fastcall Units1Click(TObject *Sender); - void __fastcall RTTI1Click(TObject *Sender); - void __fastcall Forms1Click(TObject *Sender); - void __fastcall CodeViewer1Click(TObject *Sender); - void __fastcall ClassViewer1Click(TObject *Sender); - void __fastcall Strings1Click(TObject *Sender); - void __fastcall Names1Click(TObject *Sender); - void __fastcall miUnitDumperClick(TObject *Sender); - void __fastcall miFuzzyScanKBClick(TObject *Sender); - void __fastcall miDelphi2009Click(TObject *Sender); - void __fastcall miDelphi2010Click(TObject *Sender); - void __fastcall lbNamesClick(TObject *Sender); - void __fastcall bApplyAliasClick(TObject *Sender); - void __fastcall bCancelAliasClick(TObject *Sender); - void __fastcall lbAliasesDblClick(TObject *Sender); - void __fastcall miLegendClick(TObject *Sender); - void __fastcall miCopyListClick(TObject *Sender); - void __fastcall miCommentsGeneratorClick(TObject *Sender); - void __fastcall miIDCGeneratorClick(TObject *Sender); - void __fastcall miSaveDelphiProjectClick(TObject *Sender); - void __fastcall bDecompileClick(TObject *Sender); - void __fastcall SourceCode1Click(TObject *Sender); - void __fastcall miHex2DoubleClick(TObject *Sender); - void __fastcall acFontAllExecute(TObject *Sender); - void __fastcall pmUnitItemsPopup(TObject *Sender); - void __fastcall miCopyAddressIClick(TObject *Sender); - void __fastcall miCopyAddressCodeClick(TObject *Sender); - void __fastcall miCopySource2ClipboardClick(TObject *Sender); - void __fastcall miDelphiXE1Click(TObject *Sender); - void __fastcall pmCodePopup(TObject *Sender); - void __fastcall lbFormsClick(TObject *Sender); - void __fastcall lbCodeClick(TObject *Sender); - void __fastcall pcInfoChange(TObject *Sender); - void __fastcall pcWorkAreaChange(TObject *Sender); - void __fastcall miDelphiXE2Click(TObject *Sender); - void __fastcall miPluginsClick(TObject *Sender); - void __fastcall miCopyStringsClick(TObject *Sender); - void __fastcall miViewAllClick(TObject *Sender); - void __fastcall lbSourceCodeMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); - void __fastcall cbMultipleSelectionClick(TObject *Sender); - void __fastcall lbSourceCodeDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State); - void __fastcall miSwitchSkipFlagClick(TObject *Sender); - void __fastcall miSwitchFrameFlagClick(TObject *Sender); - void __fastcall cfTry1Click(TObject *Sender); - void __fastcall miDelphiXE3Click(TObject *Sender); - void __fastcall miDelphiXE4Click(TObject *Sender); - void __fastcall miProcessDumperClick(TObject *Sender); - void __fastcall lbSourceCodeClick(TObject *Sender); - void __fastcall miSetlvartypeClick(TObject *Sender); - void __fastcall pmSourceCodePopup(TObject *Sender); - -private: // User declarations - bool ProjectLoaded; - - void __fastcall Init(); - void __fastcall AnalyzeThreadDone(TObject* Sender); - - bool __fastcall IsExe(String FileName); - bool __fastcall IsIdp(String FileName); - void __fastcall LoadFile(String FileName, int version); - void __fastcall LoadDelphiFile(int version); - void __fastcall LoadDelphiFile1(String FileName, int version, bool loadExp, bool loadImp); - void __fastcall ReadNode(TStream* stream, TTreeNode* node, char* buf); - void __fastcall OpenProject(String FileName); - bool __fastcall ImportsValid(DWORD ImpRVA, DWORD ImpSize); - int __fastcall LoadImage(FILE* f, bool loadExp, bool loadImp); - void __fastcall FindExports(); - void __fastcall FindImports(); - int __fastcall GetDelphiVersion(); - void __fastcall InitSysProcs(); - bool __fastcall IsExtendedInitTab(DWORD* unitsTab); - int __fastcall GetUnits2(String dprName); // For Delphi2 (other structure!) - int __fastcall GetUnits(String dprName); - int __fastcall GetBCBUnits(String dprName); - int __fastcall IsValidCode(DWORD fromAdr); - void __fastcall CodeHistoryPush(PPROCHISTORYREC rec); - PPROCHISTORYREC __fastcall CodeHistoryPop(); - void __fastcall ShowCodeXrefs(DWORD Adr, int selIdx); - void __fastcall ShowStringXrefs(DWORD Adr, int selIdx); - void __fastcall ShowNameXrefs(DWORD Adr, int selIdx); - void __fastcall WriteNode(TStream* stream, TTreeNode* node); - void __fastcall SaveProject(String FileName); - void __fastcall CloseProject(); - void __fastcall CleanProject(); - void __fastcall IniFileRead(); - void __fastcall IniFileWrite(); - void __fastcall AddExe2MRF(String FileName); - void __fastcall AddIdp2MRF(String FileName); - int __fastcall GetSegmentNo(DWORD Adr); - int __fastcall CodeGetTargetAdr(String line, DWORD* trgAdr); - void __fastcall OutputLine(FILE* outF, BYTE flags, DWORD adr, String content); - void __fastcall OutputCode(FILE* outF, DWORD fromAdr, String prototype, bool onlyComments); - - // Drag&Drop - TDragDropHelper dragdropHelper; - - void __fastcall wm_dropFiles(TWMDropFiles& msg); - void __fastcall DoOpenProjectFile(String FileName); - bool __fastcall ContainsUnexplored(PUnitRec recU); - // GUI update from thread - void __fastcall wm_updAnalysisStatus(TMessage& msg); - void __fastcall wm_dfmClosed(TMessage& msg); - // Tree view booster - typedef std::map< const String, TTreeNode*>TTreeNodeNameMap; - - TTreeNodeNameMap tvClassMap; - - void __fastcall ClearTreeNodeMap(); - - void __fastcall SetupAllFonts(TFont* font); - - void __fastcall miSearchFormClick(TObject *Sender); - void __fastcall miSearchNameClick(TObject *Sender); - -public: // User declarations - String AppDir; - String BinsDir; - String WrkDir; - String SourceFile; - int SysProcsNum; // Number of elements in SysProcs array - - int WhereSearch; - // UNITS - int UnitsSearchFrom; - TStringList *UnitsSearchList; - String UnitsSearchText; - // RTTIS - int RTTIsSearchFrom; - TStringList *RTTIsSearchList; - String RTTIsSearchText; - // UNITITEMS - int UnitItemsSearchFrom; - TStringList *UnitItemsSearchList; - String UnitItemsSearchText; - // FORMS - int FormsSearchFrom; - TStringList *FormsSearchList; - String FormsSearchText; - // VMTS - TTreeNode *TreeSearchFrom; - TTreeNode *BranchSearchFrom; - TStringList *VMTsSearchList; - String VMTsSearchText; - // STRINGS - int StringsSearchFrom; - TStringList *StringsSearchList; - String StringsSearchText; - // NAMES - int NamesSearchFrom; - TStringList *NamesSearchList; - String NamesSearchText; - - __fastcall TFMain_11011981(TComponent* Owner); - __fastcall ~TFMain_11011981(); - - void __fastcall DoOpenDelphiFile(int version, String FileName, bool loadExp, bool loadImp); - void __fastcall ClearPassFlags(); - DWORD __fastcall FollowInstructions(DWORD fromAdr, DWORD toAdr); - int __fastcall EstimateProcSize(DWORD fromAdr); - int __fastcall GetField(String TypeName, int Offset, String& name, String& type); - PFIELDINFO __fastcall GetField(String TypeName, int Offset, bool* vmt, DWORD* vmtAdr, String prefix); - PFIELDINFO __fastcall AddField(DWORD ProcAdr, int ProcOfs, String TypeName, BYTE Scope, int Offset, int Case, String Name, String Type); - int __fastcall GetMethodOfs(PInfoRec rec, DWORD procAdr); - PMethodRec __fastcall GetMethodInfo(PInfoRec rec, String name); - PMethodRec __fastcall GetMethodInfo(DWORD adr, char kind, int methodOfs); - - PImportNameRec __fastcall GetImportRec(DWORD adr); - void __fastcall StrapProc(int pos, int ProcId, MProcInfo* ProcInfo, bool useFixups, int procSize); - void __fastcall ShowUnits(bool showUnk); - void __fastcall ShowUnitItems(PUnitRec recU, int topIdx, int itemIdx); - void __fastcall ShowRTTIs(); - void __fastcall FillVmtList(); - void __fastcall ShowClassViewer(DWORD VmtAdr); - bool __fastcall IsUnitExist(String Name); - void __fastcall SetVmtConsts(int version); - PUnitRec __fastcall GetUnit(DWORD Adr); - String __fastcall GetUnitName(PUnitRec recU); - String __fastcall GetUnitName(DWORD Adr); - void __fastcall SetUnitName(PUnitRec recU, String name); - bool __fastcall InOneUnit(DWORD Adr1, DWORD Adr2); - void __fastcall StrapVMT(int pos, int ConstId, MConstInfo* ConstInfo); - bool __fastcall StrapCheck(int pos, MProcInfo* ProcInfo); - TTreeNode* __fastcall GetNodeByName(String AName); - - void __fastcall ScanIntfTable(DWORD adr); - void __fastcall ScanAutoTable(DWORD adr); - void __fastcall ScanInitTable(DWORD adr); - void __fastcall ScanFieldTable(DWORD adr); - void __fastcall ScanMethodTable(DWORD adr, String className); - void __fastcall ScanDynamicTable(DWORD adr); - void __fastcall ScanVirtualTable(DWORD adr); - int __fastcall GetClassHeight(DWORD adr); - String __fastcall GetCommonType(String Name1, String Name2); - void __fastcall PropagateVMTNames(DWORD adr); - - void __fastcall ShowStrings(int idx); - void __fastcall ShowNames(int idx); - // void __fastcall ScanImports(); - void __fastcall RedrawCode(); - int __fastcall AddAsmLine(DWORD Adr, String text, BYTE Flags); - void __fastcall ShowCode(DWORD fromAdr, int SelectedIdx, int XrefIdx, int topIdx); - void __fastcall AnalyzeProc(int pass, DWORD procAdr); - void __fastcall AnalyzeMethodTable(int pass, DWORD adr, const bool* Terminated); - void __fastcall AnalyzeDynamicTable(int pass, DWORD adr, const bool* Terminated); - void __fastcall AnalyzeVirtualTable(int pass, DWORD adr, const bool* Terminated); - DWORD __fastcall AnalyzeProcInitial(DWORD fromAdr); - void __fastcall AnalyzeProc1(DWORD fromAdr, char xrefType, DWORD xrefAdr, int xrefOfs, bool maybeEmb); - void __fastcall AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType); - bool __fastcall AnalyzeProc2(DWORD fromAdr, bool addArg, bool AnalyzeRetType, TList *sctx); - String __fastcall AnalyzeTypes(DWORD parentAdr, int callPos, DWORD procAdr, PRINFO registers); - String __fastcall AnalyzeArguments(DWORD fromAdr); - - int __fastcall LoadIntfTable(DWORD adr, TStringList* dstList); - int __fastcall LoadAutoTable(DWORD adr, TStringList* dstList); - int __fastcall LoadFieldTable(DWORD adr, TList* dstList); - int __fastcall LoadMethodTable(DWORD adr, TList* dstList); - int __fastcall LoadMethodTable(DWORD adr, TStringList* dstList); - int __fastcall LoadDynamicTable(DWORD adr, TList* dstList); - int __fastcall LoadDynamicTable(DWORD adr, TStringList* dstList); - int __fastcall LoadVirtualTable(DWORD adr, TList* dstList); - int __fastcall LoadVirtualTable(DWORD adr, TStringList* dstList); - void __fastcall FillClassViewerOne(int n, TStringList* tmpList, const bool* terminated); - TTreeNode* __fastcall AddClassTreeNode(TTreeNode* node, String name); - // Function - void __fastcall EditFunction(DWORD Adr); - String __fastcall MakeComment(PPICODE Picode); - void __fastcall InitAliases(bool find); - void __fastcall CopyAddress(String line, int ofs, int bytes); - void __fastcall GoToXRef(TObject *Sender); - // void __fastcall ChangeDelphiHighlightTheme(TObject *Sender); - - BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, wm_dropFiles); - VCL_MESSAGE_HANDLER(WM_UPDANALYSISSTATUS, TMessage, wm_updAnalysisStatus); - VCL_MESSAGE_HANDLER(WM_DFMCLOSED, TMessage, wm_dfmClosed); - END_MESSAGE_MAP(TForm) - - // Treenode booster for analysis - void __fastcall AddTreeNodeWithName(TTreeNode* node, const String& name); - TTreeNode* __fastcall FindTreeNodeByName(const String& name); - - // show Form by its dfm object - void __fastcall ShowDfm(TDfm* dfm); - // bool __fastcall ImportIdp(String fileName); -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFMain_11011981 *FMain_11011981; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/Plugins.cpp b/Sources/Forms/Plugins.cpp deleted file mode 100644 index f831612..0000000 --- a/Sources/Forms/Plugins.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// --------------------------------------------------------------------------- - -#include -#pragma hdrstop - -#include "Plugins.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" - -void(__stdcall*fnRegisterPlugIn)(LPCTSTR*); -void(__stdcall*fnAboutPlugIn)(void); - -TFPlugins *FPlugins; - -// --------------------------------------------------------------------------- -__fastcall TFPlugins::TFPlugins(TComponent* Owner) : TForm(Owner) { - PluginsPath = ""; - PluginName = ""; -} - -// --------------------------------------------------------------------------- -void __fastcall TFPlugins::FormShow(TObject *Sender) { - TSearchRec sr; - - cklbPluginsList->Clear(); - if (PluginsPath != "") { - Screen->Cursor = crHourGlass; - String curDir = GetCurrentDir(); - ChDir(PluginsPath); - if (!FindFirst("*.dll", faArchive, sr)) { - do { - HINSTANCE hModule = LoadLibrary(AnsiString(sr.Name).c_str()); - if (hModule) { - String info = ""; - fnRegisterPlugIn = (void(__stdcall*)(LPCTSTR*))GetProcAddress(hModule, "RegisterPlugIn"); - if (fnRegisterPlugIn) { - LPCTSTR ptr; - fnRegisterPlugIn(&ptr); - info = ptr; - } - cklbPluginsList->Items->Add(sr.Name + " - " + info); - FreeLibrary(hModule); - } - } - while (!FindNext(sr)); - - FindClose(sr); - } - ChDir(curDir); - Screen->Cursor = crDefault; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFPlugins::cklbPluginsListClickCheck(TObject *Sender) { - if (cklbPluginsList->State[cklbPluginsList->ItemIndex]) { - for (int n = 0; n < cklbPluginsList->Items->Count; n++) { - cklbPluginsList->State[n] = (n == cklbPluginsList->ItemIndex); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFPlugins::cklbPluginsListDblClick(TObject *Sender) { - String filename = ""; - String line = cklbPluginsList->Items->Strings[cklbPluginsList->ItemIndex]; - int pos = line.Pos('-'); - if (pos > 0) - filename = line.SubString(1, pos - 1).Trim(); - if (filename != "") { - HINSTANCE hModule = LoadLibrary(AnsiString(PluginsPath + "\\" + filename).c_str()); - if (hModule) { - fnAboutPlugIn = (void(__stdcall*)(void))GetProcAddress(hModule, "AboutPlugIn"); - if (fnAboutPlugIn) - fnAboutPlugIn(); - FreeLibrary(hModule); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TFPlugins::bOkClick(TObject *Sender) { - PluginName = ""; - for (int n = 0; n < cklbPluginsList->Items->Count; n++) { - if (cklbPluginsList->State[n]) { - String line = cklbPluginsList->Items->Strings[n]; - int pos = line.Pos('-'); - if (pos > 0) - PluginName = line.SubString(1, pos - 1).Trim(); - break; - } - } - ModalResult = mrOk; -} - -// --------------------------------------------------------------------------- -void __fastcall TFPlugins::bCancelClick(TObject *Sender) { - PluginName = ""; - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFPlugins::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/Plugins.h b/Sources/Forms/Plugins.h deleted file mode 100644 index 7a642a3..0000000 --- a/Sources/Forms/Plugins.h +++ /dev/null @@ -1,37 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef PluginsH -#define PluginsH -// --------------------------------------------------------------------------- -#include -#include -#include -#include - -// --------------------------------------------------------------------------- -class TFPlugins : public TForm { -__published: // IDE-managed Components - TCheckListBox *cklbPluginsList; - TButton *bOk; - TButton *bCancel; - - void __fastcall FormShow(TObject *Sender); - void __fastcall cklbPluginsListClickCheck(TObject *Sender); - void __fastcall cklbPluginsListDblClick(TObject *Sender); - void __fastcall bOkClick(TObject *Sender); - void __fastcall bCancelClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: // User declarations -public: // User declarations - __fastcall TFPlugins(TComponent* Owner); - - String PluginsPath; - String PluginName; -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFPlugins *FPlugins; -// --------------------------------------------------------------------------- -#endif - \ No newline at end of file diff --git a/Sources/Forms/ProgressBar.cpp b/Sources/Forms/ProgressBar.cpp deleted file mode 100644 index 81609f8..0000000 --- a/Sources/Forms/ProgressBar.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// --------------------------------------------------------------------------- - -#include -#pragma hdrstop - -#include "ProgressBar.h" -#include "Threads.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" -TFProgressBar *FProgressBar; - -// --------------------------------------------------------------------------- -__fastcall TFProgressBar::TFProgressBar(TComponent* Owner) : TForm(Owner) { -} - -// --------------------------------------------------------------------------- -void __fastcall TFProgressBar::FormShow(TObject *Sender) { - pb->Position = 0; - sb->Panels->Items[0]->Text = ""; - sb->Panels->Items[1]->Text = ""; -} - -// --------------------------------------------------------------------------- -void __fastcall TFProgressBar::StartProgress(String text0, String text1, int steps) { - pb->Min = 0; - pb->Max = steps; - pb->Step = 1; - pb->Position = 0; - pb->Update(); - sb->Panels->Items[0]->Text = text0; - sb->Panels->Items[1]->Text = text1; - sb->Update(); -} - -// --------------------------------------------------------------------------- -void __fastcall TFProgressBar::wm_updAnalysisStatus(TMessage& msg) { - if (taStartPrBar == msg.WParam) { - const ThreadAnalysisData* startOperation = (ThreadAnalysisData*)msg.LParam; - FProgressBar->StartProgress(startOperation ? startOperation->sbText : String(""), "", startOperation ? startOperation->pbSteps : 0); - if (startOperation) - delete startOperation; - } - else if (taUpdatePrBar == msg.WParam) { - FProgressBar->pb->StepIt(); - FProgressBar->pb->Invalidate(); - } - else if (taUpdateStBar == msg.WParam) { - const ThreadAnalysisData* updStatusBar = (ThreadAnalysisData*)msg.LParam; - FProgressBar->sb->Panels->Items[1]->Text = updStatusBar ? updStatusBar->sbText : String("?"); - FProgressBar->sb->Invalidate(); - - if (updStatusBar) - delete updStatusBar; - Application->ProcessMessages(); - } -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/ProgressBar.h b/Sources/Forms/ProgressBar.h deleted file mode 100644 index afcd21f..0000000 --- a/Sources/Forms/ProgressBar.h +++ /dev/null @@ -1,35 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef ProgressBarH -#define ProgressBarH -// --------------------------------------------------------------------------- - -#include -#include -#include -#include "Main.h" -// #include "sysmac.h" - -// #define WM_UPDANALYSISSTATUS WM_APP + 1 -// --------------------------------------------------------------------------- -class TFProgressBar : public TForm { -__published: // IDE-managed Components - TProgressBar *pb; - TStatusBar *sb; - - void __fastcall FormShow(TObject *Sender); - -private: // User declarations -public: // User declarations - __fastcall TFProgressBar(TComponent* Owner); - void __fastcall StartProgress(String text0, String text1, int steps); - void __fastcall wm_updAnalysisStatus(TMessage& msg); - - BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_UPDANALYSISSTATUS, TMessage, wm_updAnalysisStatus); - END_MESSAGE_MAP(TForm) -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFProgressBar *FProgressBar; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/StringInfo.cpp b/Sources/Forms/StringInfo.cpp deleted file mode 100644 index b14bfde..0000000 --- a/Sources/Forms/StringInfo.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "StringInfo.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" -TFStringInfo_11011981 *FStringInfo_11011981; - -// --------------------------------------------------------------------------- -__fastcall TFStringInfo_11011981::TFStringInfo_11011981(TComponent* Owner) : TForm(Owner) { -} - -// --------------------------------------------------------------------------- -void __fastcall TFStringInfo_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_ESCAPE) - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFStringInfo_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/StringInfo.h b/Sources/Forms/StringInfo.h deleted file mode 100644 index 51e01a6..0000000 --- a/Sources/Forms/StringInfo.h +++ /dev/null @@ -1,25 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef StringInfoH -#define StringInfoH -// --------------------------------------------------------------------------- -#include -#include -#include - -// --------------------------------------------------------------------------- -class TFStringInfo_11011981 : public TForm { -__published: // IDE-managed Components - TMemo *memStringInfo; - - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall FormCreate(TObject *Sender); - -private: // User declarations -public: // User declarations - __fastcall TFStringInfo_11011981(TComponent* Owner); -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFStringInfo_11011981 *FStringInfo_11011981; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/TypeInfo2.cpp b/Sources/Forms/TypeInfo2.cpp deleted file mode 100644 index 40cd6eb..0000000 --- a/Sources/Forms/TypeInfo2.cpp +++ /dev/null @@ -1,1364 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "TypeInfo2.h" -#include "Main.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" - -extern DWORD ImageBase; -extern DWORD CodeBase; -extern DWORD *Flags; -extern PInfoRec *Infos; -extern BYTE *Code; -extern int DelphiVersion; -extern TList *TypeList; -extern MKnowledgeBase KnowledgeBase; - -TFTypeInfo_11011981 *FTypeInfo_11011981; - -// --------------------------------------------------------------------------- -__fastcall TFTypeInfo_11011981::TFTypeInfo_11011981(TComponent* Owner) : TForm(Owner) { -} - -// --------------------------------------------------------------------------- -void __fastcall TFTypeInfo_11011981::ShowKbInfo(MTypeInfo* tInfo) { - WORD Len; - String line; - - memDescription->ReadOnly = True; - Panel1->Visible = False; - - if (tInfo->ModuleID != 0xFFFF) - Caption = KnowledgeBase.GetModuleName(tInfo->ModuleID) + "."; - Caption = Caption + tInfo->TypeName; - if (tInfo->Size) - Caption = Caption + " (size = " + Val2Str0(tInfo->Size) + ")"; - - memDescription->Clear(); - if (tInfo->Decl != "") - memDescription->Lines->Add(tInfo->Decl); - if (tInfo->FieldsNum) { - memDescription->Lines->Add("//FIELDS//"); - BYTE *p = tInfo->Fields; - FIELDINFO fInfo; - - for (int n = 0; n < tInfo->FieldsNum; n++) { - fInfo.Scope = *p; - p++; - fInfo.Offset = *((int*)p); - p += 4; - fInfo.Case = *((int*)p); - p += 4; - Len = *((WORD*)p); - p += 2; - fInfo.Name = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - fInfo.Type = TrimTypeName(String((char*)p, Len)); - p += Len + 1; - - line = "f" + Val2Str0(fInfo.Offset) + " "; - - switch (fInfo.Scope) { - case 9: - line += "private"; - break; - case 10: - line += "protected"; - break; - case 11: - line += "public"; - break; - case 12: - line += "published"; - break; - } - if (fInfo.Case != -1) - line += " case " + String(fInfo.Case); - line += " " + fInfo.Name + ":" + fInfo.Type; - memDescription->Lines->Add(line); - } - } - if (tInfo->PropsNum) { - memDescription->Lines->Add("//PROPERTIES//"); - BYTE *p = tInfo->Props; - PROPINFO pInfo; - - for (int n = 0; n < tInfo->PropsNum; n++) { - pInfo.Scope = *p; - p++; - pInfo.Index = *((int*)p); - p += 4; - pInfo.DispID = *((int*)p); - p += 4; - Len = *((WORD*)p); - p += 2; - pInfo.Name = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - pInfo.TypeDef = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - pInfo.ReadName = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - pInfo.WriteName = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - pInfo.StoredName = String((char*)p, Len); - p += Len + 1; - - line = ""; - - switch (pInfo.Scope) { - case 9: - line += "private"; - break; - case 10: - line += "protected"; - break; - case 11: - line += "public"; - break; - case 12: - line += "published"; - break; - } - - line += " " + pInfo.Name + ":" + pInfo.TypeDef; - line += " " + pInfo.ReadName; - line += " " + pInfo.WriteName; - line += " " + pInfo.StoredName; - - if (pInfo.Index != -1) { - switch (pInfo.Index & 6) { - case 2: - line += " read"; - break; - case 4: - line += " write"; - break; - } - } - - memDescription->Lines->Add(line); - } - } - if (tInfo->MethodsNum) { - memDescription->Lines->Add("//METHODS//"); - BYTE *p = tInfo->Methods; - METHODINFO mInfo; - - for (int n = 0; n < tInfo->MethodsNum; n++) { - mInfo.Scope = *p; - p++; - mInfo.MethodKind = *p; - p++; - Len = *((WORD*)p); - p += 2; - mInfo.Prototype = String((char*)p, Len); - p += Len + 1; - - line = ""; - - switch (mInfo.Scope) { - case 9: - line += "private"; - break; - case 10: - line += "protected"; - break; - case 11: - line += "public"; - break; - case 12: - line += "published"; - break; - } - - line += " " + mInfo.Prototype; - memDescription->Lines->Add(line); - } - } - if (tInfo->Dump) { - memDescription->Lines->Add("//Dump//"); - BYTE *p = tInfo->Dump; - line = ""; - for (int n = 0; n < tInfo->DumpSz; n++) { - if (n) - line += " "; - line += Val2Str2((int) * p); - p++; - } - memDescription->Lines->Add(line); - } - ShowModal(); -} - -// --------------------------------------------------------------------------- -String __fastcall GetVarTypeString(int val) { - String res = ""; - switch (val) { - case 0: - res = "Empty"; - break; - case 1: - res = "Null"; - break; - case 2: - res = "Smallint"; - break; - case 3: - res = "Integer"; - break; - case 4: - res = "Single"; - break; - case 5: - res = "Double"; - break; - case 6: - res = "Currency"; - break; - case 7: - res = "Date"; - break; - case 8: - res = "OleStr"; - break; - case 9: - res = "Dispatch"; - break; - case 0xA: - res = "Error"; - break; - case 0xB: - res = "Boolean"; - break; - case 0xC: - res = "Variant"; - break; - case 0xD: - res = "Unknown"; - break; - case 0xE: - res = "Decimal"; - break; - case 0xF: - res = "Undef0F"; - break; - case 0x10: - res = "ShortInt"; - break; - case 0x11: - res = "Byte"; - break; - case 0x12: - res = "Word"; - break; - case 0x13: - res = "LongWord"; - break; - case 0x14: - res = "Int64"; - break; - case 0x15: - res = "Word64"; - break; - case 0x48: - res = "StrArg"; - break; - case 0x100: - res = "String"; - break; - case 0x101: - res = "Any"; - break; - case 0xFFF: - res = "TypeMask"; - break; - case 0x2000: - res = "Array"; - break; - case 0x4000: - res = "ByRef"; - break; - } - return res; -} - -// --------------------------------------------------------------------------- -String __fastcall TFTypeInfo_11011981::GetRTTI(DWORD adr) { - bool found; - BYTE floatType, methodKind, paramCount, numOps, ordType, callConv, paramFlags, propFlags, flags, dimCount; - WORD dw, propCount, methCnt; - DWORD minValue, maxValue, minValueB, maxValueB; - int i, m, n, vmtofs, pos, posn, spos, _ap; - __int64 minInt64Value, maxInt64Value; - int elSize, varType; // for tkDynArray - DWORD elType; // for tkDynArray - DWORD typeAdr, classVMT, parentAdr, Size, elNum, elOff, resultTypeAdr; - DWORD propType, getProc, setProc, storedProc, methAdr, procSig; - BYTE GUID[16]; - String typname, name, FldFileName; - FILE *fldf; - PInfoRec recN; - - RTTIAdr = adr; - _ap = Adr2Pos(RTTIAdr); - pos = _ap; - pos += 4; - RTTIKind = Code[pos]; - pos++; - BYTE len = Code[pos]; - pos++; - RTTIName = String((char*)(Code + pos), len); - pos += len; - Caption = RTTIName; - String result = "", proto; - - switch (RTTIKind) { - case ikUnknown: - break; - case ikInteger: - case ikChar: - case ikWChar: - ordType = Code[pos]; - pos++; - minValue = *((DWORD*)(Code + pos)); - pos += 4; - maxValue = *((DWORD*)(Code + pos)); - // Signed type - if (!(ordType & 1)) - result = IntToStr((int)minValue) + ".." + IntToStr((int)maxValue); - // Unsigned type - else - result = "$" + IntToHex((__int64)minValue, 0) + ".." + "$" + IntToHex((__int64)maxValue, 0); - break; - case ikEnumeration: - result = "("; - ordType = Code[pos]; - pos++; - minValue = *((DWORD*)(Code + pos)); - pos += 4; - maxValue = *((DWORD*)(Code + pos)); - pos += 4; - // BaseTypeAdr - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - - if (SameText(RTTIName, "ByteBool") || SameText(RTTIName, "WordBool") || SameText(RTTIName, "LongBool")) { - minValue = 0; - maxValue = 1; - } - - // If BaseTypeAdr != SelfAdr then fields extracted from BaseType - if (typeAdr != RTTIAdr) { - pos = Adr2Pos(typeAdr); - pos += 4; // SelfPointer - pos++; // typeKind - len = Code[pos]; - pos++; - pos += len; // BaseClassName - pos++; // ordType - minValueB = *((DWORD*)(Code + pos)); - pos += 4; - maxValueB = *((DWORD*)(Code + pos)); - pos += 4; - pos += 4; // BaseClassPtr - } - else { - minValueB = minValue; - maxValueB = maxValue; - } - - for (i = minValueB; i <= maxValueB; i++) { - len = Code[pos]; - pos++; - if (i >= minValue && i <= maxValue) { - name = String((char*)(Code + pos), len); - if (i != minValue) - result += ", "; - result += name; - } - pos += len; - } - result += ")"; - // UnitName - len = Code[pos]; - if (IsValidName(len, pos + 1)) { - pos++; - Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; - } - break; - case ikFloat: - if (SameText(RTTIName, "Single") || SameText(RTTIName, "Double") || SameText(RTTIName, "Extended") || SameText(RTTIName, "Comp") || SameText(RTTIName, "Currency")) - result = "float"; - else { - floatType = Code[pos]; - pos++; - result = "type "; - switch (floatType) { - case FtSingle: - result += "Single"; - break; - case FtDouble: - result += "Double"; - break; - case FtExtended: - result += "Extended"; - break; - case FtComp: - result += "Comp"; - break; - case FtCurr: - result += "Currency"; - break; - } - } - break; - case ikString: - result = "String"; - break; - case ikSet: - result = "set of "; - pos++; // skip ordType - typeAdr = *((DWORD*)(Code + pos)); - result = "set of " + GetTypeName(typeAdr); - break; - case ikClass: - result = "class"; - classVMT = *((DWORD*)(Code + pos)); - pos += 4; - parentAdr = *((DWORD*)(Code + pos)); - pos += 4; - if (parentAdr) - result += "(" + GetTypeName(parentAdr) + ")"; - propCount = *((WORD*)(Code + pos)); - pos += 2; - - // UnitName - len = Code[pos]; - pos++; - Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; - pos += len; - - propCount = *((WORD*)(Code + pos)); - pos += 2; - for (i = 0; i < propCount; i++) { - propType = *((DWORD*)(Code + pos)); - pos += 4; - posn = Adr2Pos(propType); - posn += 4; - posn++; // property type - len = Code[posn]; - posn++; - typname = String((char*)(Code + posn), len); - getProc = *((DWORD*)(Code + pos)); - pos += 4; - setProc = *((DWORD*)(Code + pos)); - pos += 4; - storedProc = *((DWORD*)(Code + pos)); - pos += 4; - // idx - pos += 4; - // defval - pos += 4; - // nameIdx - pos += 2; - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - result += "\n" + name + ":" + typname; - if ((getProc & 0xFFFFFF00)) { - result += "\n read "; - if ((getProc & 0xFF000000) == 0xFF000000) - result += name + " f" + Val2Str0(getProc & 0x00FFFFFF); - else if ((getProc & 0xFF000000) == 0xFE000000) { - if ((getProc & 0x00008000)) - vmtofs = -((int)getProc & 0x0000FFFF); - else - vmtofs = getProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - getProc = *((DWORD*)(Code + posn)); - - result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(getProc); - recN = GetInfoRec(getProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - else { - result += Val2Str0(getProc); - recN = GetInfoRec(getProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - } - if ((setProc & 0xFFFFFF00)) { - result += "\n write "; - if ((setProc & 0xFF000000) == 0xFF000000) - result += name + " f" + Val2Str0(setProc & 0x00FFFFFF); - else if ((setProc & 0xFF000000) == 0xFE000000) { - if ((setProc & 0x00008000)) - vmtofs = -((int)setProc & 0x0000FFFF); - else - \ - vmtofs = setProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - setProc = *((DWORD*)(Code + posn)); - result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(setProc); - recN = GetInfoRec(setProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - else { - result += Val2Str0(setProc); - recN = GetInfoRec(setProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - } - if ((storedProc & 0xFFFFFF00)) { - result += "\n stored "; - if ((storedProc & 0xFF000000) == 0xFF000000) - result += name + " f" + Val2Str0(storedProc & 0x00FFFFFF); - else if ((storedProc & 0xFF000000) == 0xFE000000) { - if ((storedProc & 0x00008000)) - vmtofs = -((int)storedProc & 0x0000FFFF); - else - vmtofs = storedProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - storedProc = *((DWORD*)(Code + posn)); - result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(storedProc); - recN = GetInfoRec(storedProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - else { - result += Val2Str0(storedProc); - recN = GetInfoRec(storedProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - } - } - if (DelphiVersion >= 2010) { - propCount = *((WORD*)(Code + pos)); - pos += 2; - for (i = 0; i < propCount; i++) { - // Flags - propFlags = Code[pos]; - pos++; - // PPropInfo - propType = *((DWORD*)(Code + pos)); - pos += 4; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - spos = pos; - // PropInfo - pos = Adr2Pos(propType); - propType = *((DWORD*)(Code + pos)); - pos += 4; - - if (IsFlagSet(cfImport, Adr2Pos(propType))) { - recN = GetInfoRec(propType); - typname = recN->GetName(); - } - else { - posn = Adr2Pos(propType); - posn += 4; - posn++; // property type - len = Code[posn]; - posn++; - typname = String((char*)(Code + posn), len); - } - - getProc = *((DWORD*)(Code + pos)); - pos += 4; - setProc = *((DWORD*)(Code + pos)); - pos += 4; - storedProc = *((DWORD*)(Code + pos)); - pos += 4; - // idx - pos += 4; - // defval - pos += 4; - // nameIdx - pos += 2; - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - result += "\n" + name + ":" + typname; - if ((getProc & 0xFFFFFF00)) { - result += "\n read "; - if ((getProc & 0xFF000000) == 0xFF000000) - result += name + " f" + Val2Str0(getProc & 0x00FFFFFF); - else if ((getProc & 0xFF000000) == 0xFE000000) { - if ((getProc & 0x00008000)) - vmtofs = -((int)getProc & 0x0000FFFF); - else - vmtofs = getProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - getProc = *((DWORD*)(Code + pos)); - - result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(getProc); - recN = GetInfoRec(getProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - else { - result += Val2Str0(getProc); - recN = GetInfoRec(getProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - } - if ((setProc & 0xFFFFFF00)) { - result += "\n write "; - if ((setProc & 0xFF000000) == 0xFF000000) - result += name + " f" + Val2Str0(setProc & 0x00FFFFFF); - else if ((setProc & 0xFF000000) == 0xFE000000) { - if ((setProc & 0x00008000)) - vmtofs = -((int)setProc & 0x0000FFFF); - else - vmtofs = setProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - setProc = *((DWORD*)(Code + pos)); - result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(setProc); - recN = GetInfoRec(setProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - else { - result += Val2Str0(setProc); - recN = GetInfoRec(setProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - } - if ((storedProc & 0xFFFFFF00)) { - result += "\n stored "; - if ((storedProc & 0xFF000000) == 0xFF000000) - result += name + " f" + Val2Str0(storedProc & 0x00FFFFFF); - else if ((storedProc & 0xFF000000) == 0xFE000000) { - if ((storedProc & 0x00008000)) - vmtofs = -((int)storedProc & 0x0000FFFF); - else - vmtofs = storedProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - storedProc = *((DWORD*)(Code + pos)); - result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(storedProc); - recN = GetInfoRec(storedProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - else { - result += Val2Str0(storedProc); - recN = GetInfoRec(storedProc); - if (recN && recN->HasName()) - result += " " + recN->GetName(); - } - } - pos = spos; - } - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - if (DelphiVersion >= 2012) { - // ArrayPropCount - propCount = *((WORD*)(Code + pos)); - pos += 2; - for (i = 0; i < propCount; i++) { - // Flags - pos++; - // ReadIndex - pos += 2; - // WriteIndex - pos += 2; - // Name - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - result += "\n" + name; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - } - } - } - break; - case ikMethod: - methodKind = Code[pos]; - pos++; - switch (methodKind) { - case MkProcedure: - result = "procedure"; - break; - case MkFunction: - result = "function"; - break; - case MkConstructor: - result = "constructor"; - break; - case MkDestructor: - result = "destructor"; - break; - case MkClassProcedure: - result = "class procedure"; - break; - case MkClassFunction: - result = "class function"; - break; - case 6: - if (DelphiVersion < 2009) - result = "safeprocedure"; - else - result = "class constructor"; - break; - case 7: - if (DelphiVersion < 2009) - result = "safefunction"; - else - result = "operator overload"; - break; - } - - paramCount = Code[pos]; - pos++; - if (paramCount > 0) - proto = "("; - - for (i = 0; i < paramCount; i++) { - BYTE paramFlags = Code[pos]; - pos++; - if (paramFlags & PfVar) - proto += "var "; - else if (paramFlags & PfConst) - proto += "const "; - else if (paramFlags & PfArray) - proto += "array "; - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - proto += name + ":"; - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - proto += name; - if (i != paramCount - 1) - proto += "; "; - } - if (paramCount > 0) - proto += ")"; - - if (methodKind) { - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - if (DelphiVersion > 6) { - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - name = GetTypeName(typeAdr); - } - proto += ":" + name; - } - if (DelphiVersion > 6) { - // CC - callConv = Code[pos]; - pos++; - // ParamTypeRefs - pos += 4 * paramCount; - if (DelphiVersion >= 2010) { - // MethSig - procSig = *((DWORD*)(Code + pos)); - pos += 4; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - // Procedure Signature - if (procSig) { - if (IsValidImageAdr(procSig)) - posn = Adr2Pos(procSig); - else - posn = _ap + procSig; - // Flags - flags = Code[posn]; - posn++; - if (flags != 0xFF) { - // CC - callConv = Code[posn]; - posn++; - // ResultType - resultTypeAdr = *((DWORD*)(Code + posn)); - posn += 4; - // ParamCount - paramCount = Code[posn]; - posn++; - if (paramCount > 0) - proto = "("; - for (i = 0; i < paramCount; i++) { - BYTE paramFlags = Code[posn]; - posn++; - if (paramFlags & PfVar) - proto += "var "; - else if (paramFlags & PfConst) - proto += "const "; - else if (paramFlags & PfArray) - proto += "array "; - typeAdr = *((DWORD*)(Code + posn)); - posn += 4; - len = Code[posn]; - posn++; - name = String((char*)(Code + posn), len); - posn += len; - proto += name + ":" + GetTypeName(typeAdr); - if (i != paramCount - 1) - proto += "; "; - // AttrData - dw = *((WORD*)(Code + posn)); - posn += dw; // ATR!! - } - if (paramCount > 0) - proto += ")"; - if (resultTypeAdr) - proto += ":" + GetTypeName(resultTypeAdr); - } - } - } - } - result += proto + " of object;"; - break; - case ikLString: - result = "String"; - break; - case ikWString: - result = "WideString"; - break; - case ikVariant: - result = "Variant"; - break; - case ikArray: - Size = *((DWORD*)(Code + pos)); - pos += 4; - elNum = *((DWORD*)(Code + pos)); - pos += 4; - resultTypeAdr = *((DWORD*)(Code + pos)); - pos += 4; - result = "array [1.." + String(elNum); - if (DelphiVersion >= 2010) { - result = "array ["; - // DimCount - dimCount = Code[pos]; - pos++; - for (i = 0; i < dimCount; i++) { - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - if (IsValidImageAdr(typeAdr)) - result += GetTypeName(typeAdr); - else { - if (!typeAdr) { - if (dimCount == 1) - result += "1.." + String(elNum); - else - result += "1..?"; - } - else - result += "1.." + String(typeAdr); - } - if (i != dimCount - 1) - result += ","; - } - } - result += "] of " + GetTypeName(resultTypeAdr); - break; - case ikRecord: - Size = *((DWORD*)(Code + pos)); - pos += 4; - result = RTTIName + " = record//size=" + Val2Str0(Size); - elNum = *((DWORD*)(Code + pos)); - pos += 4; // FldCount - if (elNum) { - for (i = 0; i < elNum; i++) { - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - elOff = *((DWORD*)(Code + pos)); - pos += 4; - result += "\nf" + Val2Str0(elOff) + ":" + GetTypeName(typeAdr) + ";//f" + Val2Str0(elOff); - } - result += "\nend;"; - } - - if (DelphiVersion >= 2010) { - // NumOps - numOps = Code[pos]; - pos++; - for (i = 0; i < numOps; i++) // RecOps - { - pos += 4; - } - elNum = *((DWORD*)(Code + pos)); - pos += 4; // RecFldCnt - - if (elNum) { - for (i = 0; i < elNum; i++) { - // TypeRef - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - // FldOffset - elOff = *((DWORD*)(Code + pos)); - pos += 4; - // Flags - pos++; - // Name - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - result += "\n" + name + ":" + GetTypeName(typeAdr) + ";//f" + Val2Str0(elOff); - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - } - result += "\nend;"; - } - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - if (DelphiVersion >= 2012) { - methCnt = *((WORD*)(Code + pos)); - pos += 2; - if (methCnt > 0) - result += "\n//Methods:"; - for (m = 0; m < methCnt; m++) { - // Flags - pos++; - // Code - methAdr = *((DWORD*)(Code + pos)); - pos += 4; - // Name - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - result += "\n" + name; - // ProcedureSignature - // Flags - flags = Code[pos]; - pos++; - if (flags != 0xFF) { - // CC - pos++; - // ResultType - resultTypeAdr = *((DWORD*)(Code + pos)); - pos += 4; - // ParamCnt - paramCount = Code[pos]; - pos++; - if (paramCount > 0) - result += "("; - // Params - for (n = 0; n < paramCount; n++) { - // Flags - pos++; - // ParamType - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - // Name - len = Code[pos]; - pos++; - name = String((char*)(Code + pos), len); - pos += len; - result += name + ":" + GetTypeName(typeAdr); - if (n != paramCount - 1) - result += ";"; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - } - if (paramCount > 0) - result += ")"; - if (resultTypeAdr) - result += ":" + GetTypeName(resultTypeAdr); - result += ";//" + Val2Str8(methAdr); - } - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - } - } - } - break; - case ikInterface: - result = "interface"; - // IntfParent - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - if (typeAdr) - result += "(" + GetTypeName(typeAdr) + ")"; - // IntfFlags - pos++; - // GUID - memmove(GUID, &Code[pos], 16); - pos += 16; - result += Guid2String(GUID) + "\n"; - - // UnitName - len = Code[pos]; - pos++; - Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; - pos += len; - - // Methods - propCount = *((WORD*)(Code + pos)); - pos += 2; - result += "Methods Count = " + String(propCount); - if (DelphiVersion >= 6) { - // RttiCount - dw = *((WORD*)(Code + pos)); - pos += 2; - if (dw != 0xFFFF) { - if (DelphiVersion >= 2010) { - for (i = 0; i < propCount; i++) { - // Name - len = Code[pos]; - pos++; - result += "\n" + String((char*)(Code + pos), len); - pos += len; - // Kind - methodKind = Code[pos]; - pos++; - // CallConv - pos++; - // ParamCount - paramCount = Code[pos]; - pos++; - if (paramCount) - result += "("; - for (m = 0; m < paramCount; m++) { - if (m) - result += ";"; - // Flags - pos++; - // ParamName - len = Code[pos]; - pos++; - result += String((char*)(Code + pos), len); - pos += len; - // TypeName - len = Code[pos]; - pos++; - result += ":" + String((char*)(Code + pos), len); - pos += len; - // ParamType - pos += 4; - } - if (paramCount) - result += ")"; - if (methodKind) { - result += ":"; - // ResultTypeName - len = Code[pos]; - pos++; - result += String((char*)(Code + pos), len); - pos += len; - if (len) { - // ResultType - pos += 4; - } - } - } - } - else { - for (i = 0; i < propCount; i++) { - // PropType - pos += 4; - // GetProc - pos += 4; - // SetProc - pos += 4; - // StoredProc - pos += 4; - // Index - pos += 4; - // Default - pos += 4; - // NameIndex - pos += 2; - // Name - len = Code[pos]; - pos++; - result += "\n" + String((char*)(Code + pos), len); - pos += len; - } - } - } - } - break; - case ikInt64: - minInt64Value = *((__int64*)(Code + pos)); - pos += sizeof(__int64); - maxInt64Value = *((__int64*)(Code + pos)); - result = IntToStr(minInt64Value) + ".." + IntToStr(maxInt64Value); - break; - case ikDynArray: - // elSize - elSize = *((DWORD*)(Code + pos)); - pos += 4; - // elType - elType = *((DWORD*)(Code + pos)); - pos += 4; - result = "array of " + GetTypeName(elType); - // varType - varType = *((DWORD*)(Code + pos)); - pos += 4; - if (DelphiVersion >= 6) { - // elType2 - pos += 4; - // UnitName - len = Code[pos]; - pos++; - Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; - pos += len; - } - if (DelphiVersion >= 2010) { - // DynArrElType - elType = *((DWORD*)(Code + pos)); - result = "array of " + GetTypeName(elType); - } - result += ";"; - if (elSize) - result += "\n//elSize = " + Val2Str0(elSize); - if (varType != -1) - result += "\n//varType equivalent: var" + GetVarTypeString(varType); - break; - case ikUString: - result = "UString"; - break; - case ikClassRef: // 0x13 - typeAdr = *((DWORD*)(Code + pos)); - if (typeAdr) - result = "class of " + GetTypeName(typeAdr); - break; - case ikPointer: // 0x14 - typeAdr = *((DWORD*)(Code + pos)); - if (typeAdr) - result = "^" + GetTypeName(typeAdr); - break; - case ikProcedure: // 0x15 - result = RTTIName; - // MethSig - procSig = *((DWORD*)(Code + pos)); - pos += 4; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - // Procedure Signature - if (procSig) { - if (IsValidImageAdr(procSig)) - pos = Adr2Pos(procSig); - else - pos = _ap + procSig; - // Flags - flags = Code[pos]; - pos++; - if (flags != 0xFF) { - // CallConv - callConv = Code[pos]; - pos++; - // ResultType - resultTypeAdr = *((DWORD*)(Code + pos)); - pos += 4; - if (resultTypeAdr) - result = "function "; - else - result = "procedure "; - result += RTTIName; - - // ParamCount - paramCount = Code[pos]; - pos++; - - if (paramCount) - result += "("; - for (i = 0; i < paramCount; i++) { - // Flags - paramFlags = Code[pos]; - pos++; - if (paramFlags & 1) - result += "var "; - if (paramFlags & 2) - result += "const "; - // ParamType - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - // Name - len = Code[pos]; - pos++; - result += String((char*)(Code + pos), len) + ":"; - pos += len; - result += GetTypeName(typeAdr); - if (i != paramCount - 1) - result += "; "; - // AttrData - dw = *((WORD*)(Code + pos)); - pos += dw; // ATR!! - } - if (paramCount) - result += ")"; - - if (resultTypeAdr) - result += ":" + GetTypeName(resultTypeAdr); - result += ";"; - switch (callConv) { - case 1: - result += " cdecl;"; - break; - case 2: - result += " pascal;"; - break; - case 3: - result += " stdcall;"; - break; - case 4: - result += " safecall;"; - break; - } - } - } - break; - } - return result; -} - -// --------------------------------------------------------------------- -void __fastcall TFTypeInfo_11011981::ShowRTTI(DWORD adr) { - memDescription->ReadOnly = True; - Panel1->Visible = False; - - String line = GetRTTI(adr); - if (line != "") { - memDescription->Clear(); - int len = line.Length(); - int b = 1, e = line.Pos("\n"); - while (1) { - if (e) { - line[e] = ' '; - memDescription->Lines->Add(line.SubString(b, e - b)); - } - else { - memDescription->Lines->Add(line.SubString(b, len - b + 1)); - break; - } - b = e + 1; - e = line.Pos("\n"); - } - if (RTTIKind == ikDynArray) { - memDescription->ReadOnly = False; - Panel1->Visible = True; - } - ShowModal(); - } -} - -// --------------------------------------------------------------------- -String __fastcall Guid2String(BYTE* Guid) { - int n; - char sbyte[8]; - String Result = "['{"; - - for (int i = 0; i < 16; i++) { - switch (i) { - case 0: - case 1: - case 2: - case 3: - n = 3 - i; - break; - case 4: - n = 5; - break; - case 5: - n = 4; - break; - case 6: - n = 7; - break; - case 7: - n = 6; - break; - default: - n = i; - break; - } - if (i == 4 || i == 6 || i == 8 || i == 10) - Result += '-'; - sprintf(sbyte, "%02X", Guid[n]); - Result += String(sbyte); - } - Result += "}']"; - return Result; -} - -// --------------------------------------------------------------------- -void __fastcall TFTypeInfo_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (Key == VK_ESCAPE) - ModalResult = mrCancel; -} - -// --------------------------------------------------------------------------- -void __fastcall TFTypeInfo_11011981::bSaveClick(TObject *Sender) { - BYTE len; - int pos, p; - String line, decl; - - for (int n = 0; n < memDescription->Lines->Count; n++) { - line = memDescription->Lines->Strings[n].Trim(); - if (line == "") - continue; - decl += line; - } - decl = decl.Trim(); - p = decl.Pos(";"); - if (p > 0) { - decl = decl.SubString(1, p - 1); - } - - pos = Adr2Pos(RTTIAdr); - pos += 4; - pos++; // Kind - len = Code[pos]; - pos++; - pos += len; // Name - - switch (RTTIKind) { - case ikDynArray: - // elSize - pos += 4; - // elType - *((DWORD*)(Code + pos)) = GetOwnTypeAdr(GetArrayElementType(decl)); - break; - } - ModalResult = mrOk; -} - -// --------------------------------------------------------------------------- -void __fastcall TFTypeInfo_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/TypeInfo2.h b/Sources/Forms/TypeInfo2.h deleted file mode 100644 index 9b0eac5..0000000 --- a/Sources/Forms/TypeInfo2.h +++ /dev/null @@ -1,39 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef TypeInfo2H -#define TypeInfo2H -// --------------------------------------------------------------------------- -#include -#include -#include -#include -#include "KnowledgeBase.h" -// --------------------------------------------------------------------------- -String __fastcall Guid2String(BYTE* Guid); - -// --------------------------------------------------------------------------- -class TFTypeInfo_11011981 : public TForm { -__published: // IDE-managed Components - TMemo *memDescription; - TPanel *Panel1; - TButton *bSave; - - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall bSaveClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - -private: // User declarations - int RTTIKind; - DWORD RTTIAdr; - String RTTIName; - -public: // User declarations - __fastcall TFTypeInfo_11011981(TComponent* Owner); - void __fastcall ShowKbInfo(MTypeInfo* tInfo); - String __fastcall GetRTTI(DWORD adr); - void __fastcall ShowRTTI(DWORD adr); -}; - -// --------------------------------------------------------------------------- -extern PACKAGE TFTypeInfo_11011981 *FTypeInfo_11011981; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Forms/UfrmFormTree.cpp b/Sources/Forms/UfrmFormTree.cpp deleted file mode 100644 index 4dce220..0000000 --- a/Sources/Forms/UfrmFormTree.cpp +++ /dev/null @@ -1,336 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -/* - #include - #include - */ - -#include -#include "UfrmFormTree.h" -#include "Main.h" -#include "Misc.h" - -// --------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma resource "*.dfm" -// --------------------------------------------------------------------------- -// as: todo: refactor! extern linkage is bad practice (idea: use singleton) -extern TResourceInfo *ResInfo; -extern PInfoRec *Infos; -extern DWORD CodeBase; - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::AddEventsToNode(String compName, TTreeNode* dstNode, TList* evList) { - const int evCnt = evList->Count; - for (int m = 0; m < evCnt; m++) { - EventListItem *item = (EventListItem*)evList->Items[m]; - if (SameText(item->CompName, compName)) { - tvForm->Items->AddChildObject(dstNode, MakeNodeEventCaption(item), (void*)item->Adr); - } - } -} - -// --------------------------------------------------------------------------- -__fastcall TIdrDfmFormTree_11011981::TIdrDfmFormTree_11011981(TComponent* Owner) : TForm(Owner) { - ThinkCursor waitCursor; - - TForm* frmOwner = (TForm*)Owner; - - const int compCnt = frmOwner->ComponentCount; - if (compCnt > 1) - Caption = frmOwner->Name + " (" + String(compCnt) + " components)"; - else - Caption = frmOwner->Name + " (1 component)"; - - std::auto_ptrevList(new TList); - ResInfo->GetEventsList(frmOwner->Name, evList.get()); - - tvForm->Items->BeginUpdate(); - - TTreeNode* rootNode = tvForm->Items->AddObject(0, frmOwner->Name, frmOwner); - AddTreeNodeWithTag(rootNode, frmOwner); - AddEventsToNode(frmOwner->Name, rootNode, evList.get()); - - TComponent* currComp; - TControl* currControl; - TTreeNode *parentNode, *childNode; - bool externalParent = false; - String externalNames; - - for (int i = 0; i < compCnt; i++) { - currComp = frmOwner->Components[i]; - if (currComp == this) - continue; // Don't display Form TreeView - - String tnCaption = MakeNodeCaption(currComp); - - TComponent* parCompo = currComp->GetParentComponent(); - - if (currComp->HasParent()) { - // in some very rare cases parent could be located in another module! - // so in this case we have true for currComp->HasParent() but NULL for parCompo - if (!parCompo) { - externalParent = true; - - if (!externalNames.IsEmpty()) - externalNames += ", "; - externalNames += tnCaption; - } - - String parName = parCompo ? parCompo->Name : String("N/A"); - String ownName = currComp->Owner->Name; - - parentNode = FindTreeNodeByTag(parCompo); - - // tricky case for special components (eg: TPage, TTabPage) - // they are a) noname (but renamed in IDR) - // b) not present in Components[] array - - if (!parentNode && parCompo) { - TComponent* parCompo2 = parCompo->GetParentComponent(); - String parName2 = parCompo2->Name; - TTreeNode *parentNode2 = FindTreeNodeByTag(parCompo2); - - // add noname parent - parentNode = tvForm->Items->AddChildObject(parentNode2, MakeNodeCaption(parCompo), parCompo); - AddTreeNodeWithTag(parentNode, parCompo); - } - } - else - parentNode = FindTreeNodeByTag(currComp->Owner); - - childNode = tvForm->Items->AddChildObject(parentNode, tnCaption, currComp); - AddTreeNodeWithTag(childNode, currComp); - AddEventsToNode(currComp->Name, childNode, evList.get()); - } - - rootNode->Expand(false); - tvForm->Items->EndUpdate(); - - if (externalParent) { - Application->MessageBox(("Form has some component classes defined in external modules:\r\n" + externalNames + ".\r\n\r\nVisualization of these components is not yet implemented").c_str(), - L"Warning", MB_OK | MB_ICONWARNING); - } -} - -// --------------------------------------------------------------------------- -String TIdrDfmFormTree_11011981::MakeNodeCaption(TComponent* curCompo) { - String className = curCompo->ClassName(); - - IdrDfmDefaultControl* replControl; - if ((replControl = dynamic_cast(curCompo)) != 0) - className = "!" + replControl->GetOrigClassName(); - - return curCompo->Name + ":" + className; - - // as: old code - // return curCompo->Name + ":" + curCompo->ClassName(); -} - -// --------------------------------------------------------------------------- -String TIdrDfmFormTree_11011981::MakeNodeEventCaption(void* item) { - if (((EventListItem*)item)->Adr) { - PInfoRec recN = GetInfoRec(((EventListItem*)item)->Adr); - if (recN && recN->HasName()) - return ((EventListItem*)item)->EventName + "=" + recN->GetName(); - } - return ((EventListItem*)item)->EventName; -} - -// --------------------------------------------------------------------------- -TTreeNode* __fastcall TIdrDfmFormTree_11011981::FindTreeNodeByTag(const void* tag) { - TTreeNodeMap::const_iterator it = NodesMap.find(tag); - if (it != NodesMap.end()) - return it->second; - - return 0; -} - -// --------------------------------------------------------------------------- -TTreeNode* __fastcall TIdrDfmFormTree_11011981::FindTreeNodeByText(TTreeNode* nodeFrom, const String& txt, bool caseSensitive) { - TTreeNode* tn = 0; - bool startScan = nodeFrom ? false : true; - - TTreeNodes* nodes = tvForm->Items; - for (int i = 0; i < nodes->Count; ++i) { - if (!startScan) { - if (nodeFrom == nodes->Item[i]) - startScan = true; - continue; - } - - String ttt = nodes->Item[i]->Text; - if ((caseSensitive && AnsiContainsStr(nodes->Item[i]->Text, txt)) || (!caseSensitive && AnsiContainsText(nodes->Item[i]->Text, txt))) { - tn = nodes->Item[i]; - break; - } - } - - return tn; -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::AddTreeNodeWithTag(TTreeNode* node, const void* tag) { - NodesMap[tag] = node; -} - -// --------------------------------------------------------------------------- -bool __fastcall TIdrDfmFormTree_11011981::IsEventNode(TTreeNode* selNode) { - return (selNode && !selNode->Text.IsEmpty() && selNode->Text.Pos("=")); -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - if (VK_ESCAPE == Key) { - Key = 0; - Close(); - ((TForm*)Owner)->SetFocus(); - } - else if (VK_F3 == Key) { - dlgFindFind(Sender); - } - else if (Shift.Contains(ssCtrl) && 'F' == Key) { - dlgFind->Execute(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::tvFormKeyPress(TObject *Sender, char &Key) { - if (VK_RETURN == Key) { - Key = 0; - tvFormDblClick(Sender); - } -} - -// --------------------------------------------------------------------------- -void TIdrDfmFormTree_11011981::BorderTheControl(TControl* aControl) { - std::auto_ptrC(new TControlCanvas()); - TWinControl* parCtrl = aControl->Parent; - - if (!parCtrl) - parCtrl = (TWinControl*)aControl; - - HDC aDC; - TRect aRect; - HWND aHandle; - bool bMenu; - - C->Control = parCtrl; - - aHandle = parCtrl->Handle; - aDC = GetWindowDC(aHandle); - C->Handle = aDC; - C->Brush->Style = bsSolid; - C->Pen->Width = 1; - C->Pen->Color = clRed; - - aRect = aControl->ClientRect; - TForm* frm = dynamic_cast(parCtrl); - bMenu = frm && frm->Menu != 0; - AdjustWindowRectEx(&aRect, GetWindowLong(aHandle, GWL_STYLE), bMenu, GetWindowLong(aHandle, GWL_EXSTYLE)); - MoveWindowOrg(aDC, -aRect.Left, -aRect.Top); - - if (parCtrl == aControl) { - aRect = aControl->ClientRect; - } - else { - aRect = aControl->BoundsRect; - InflateRect(&aRect, 2, 2); - } - // C->Rectangle(aRect); - C->DrawFocusRect(aRect); - - ReleaseDC(aHandle, aDC); -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::tvFormDblClick(TObject *Sender) { - TTreeNode* selNode = tvForm->Selected; - if (!selNode) - return; - - if (IsEventNode(selNode)) { - const DWORD Adr = (const DWORD)selNode->Data; - if (Adr && IsValidCodeAdr(Adr)) { - PInfoRec recN = GetInfoRec(Adr); - if (recN) { - if (recN->kind == ikVMT) - FMain_11011981->ShowClassViewer(Adr); - else - FMain_11011981->ShowCode(Adr, 0, -1, -1); - } - } - return; - } - - TControl* selControl = dynamic_cast((TComponent*)selNode->Data); - if (!selControl) - return; - - TWinControl* parControl = selControl->Parent; - if (!parControl) - return; - - TForm* ownerForm = (TForm*)Owner; - - ownerForm->BringToFront(); - selControl->BringToFront(); - - for (int i = 0; i < 2; i++) { - BorderTheControl(selControl); - selControl->Hide(); - selControl->Update(); - Sleep(150); - BorderTheControl(selControl); - selControl->Show(); - selControl->Update(); - Sleep(150); - } - - BringToFront(); -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::dlgFindFind(TObject *Sender) { - bool caseSensitive = dlgFind->Options.Contains(frMatchCase); - - TTreeNode* tn = FindTreeNodeByText(tvForm->Selected, dlgFind->FindText, caseSensitive); - if (!tn) - tn = FindTreeNodeByText(0, dlgFind->FindText.Trim(), caseSensitive); - - if (tn) { - tvForm->Selected = tn; - tn->Expand(false); - tvForm->SetFocus(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::Expand1Click(TObject *Sender) { - if (tvForm->Selected) - tvForm->Selected->Expand(true); -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::Collapse1Click(TObject *Sender) { - if (tvForm->Selected) - tvForm->Selected->Collapse(false); -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::Find1Click(TObject *Sender) { - dlgFind->Execute(); -} -// --------------------------------------------------------------------------- - -void __fastcall TIdrDfmFormTree_11011981::FormClose(TObject *Sender, TCloseAction &Action) { - dlgFind->CloseDialog(); -} - -// --------------------------------------------------------------------------- -void __fastcall TIdrDfmFormTree_11011981::FormCreate(TObject *Sender) { - ScaleForm(this); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Forms/UfrmFormTree.h b/Sources/Forms/UfrmFormTree.h deleted file mode 100644 index d79878c..0000000 --- a/Sources/Forms/UfrmFormTree.h +++ /dev/null @@ -1,72 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef UfrmFormTreeH -#define UfrmFormTreeH -// --------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -// --------------------------------------------------------------------------- -typedef std::map< const void*, TTreeNode*>TTreeNodeMap; - -// --------------------------------------------------------------------------- -class TIdrDfmFormTree_11011981 : public TForm { -__published: // IDE-managed Components - TTreeView *tvForm; - TFindDialog *dlgFind; - TPopupMenu *mnuTree; - TMenuItem *Expand1; - TMenuItem *Collapse1; - TMenuItem *Find1; - - void __fastcall tvFormKeyPress(TObject *Sender, char &Key); - void __fastcall tvFormDblClick(TObject *Sender); - void __fastcall dlgFindFind(TObject *Sender); - void __fastcall Expand1Click(TObject *Sender); - void __fastcall Collapse1Click(TObject *Sender); - void __fastcall Find1Click(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall FormCreate(TObject *Sender); - -private: // User declarations - String MakeNodeCaption(TComponent* curCompo); - String MakeNodeEventCaption(void* item); - void BorderTheControl(TControl* aControl); - - void __fastcall AddEventsToNode(String compName, TTreeNode* dstNode, TList* evList); - TTreeNode* __fastcall FindTreeNodeByText(TTreeNode* nodeFrom, const String& txt, bool caseSensitive); - TTreeNode* __fastcall FindTreeNodeByTag(const void* tag); - void __fastcall AddTreeNodeWithTag(TTreeNode* node, const void* tag); - - TTreeNodeMap NodesMap; - - bool __fastcall IsEventNode(TTreeNode* selNode); - -public: // User declarations - __fastcall TIdrDfmFormTree_11011981(TComponent* Owner); -}; - -// --------------------------------------------------------------------------- -// show thinking cursor (ctor - show, dtor - hide with restore previous) - -class ThinkCursor { -public: - inline ThinkCursor() { - prevCursor = Screen->Cursor; - Screen->Cursor = crHourGlass; - Application->ProcessMessages(); - } - - inline ~ThinkCursor() { - Screen->Cursor = prevCursor; - } - -private: - Controls::TCursor prevCursor; -}; - -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Decompiler.cpp b/Sources/Libs/Decompiler.cpp deleted file mode 100644 index 9039de3..0000000 --- a/Sources/Libs/Decompiler.cpp +++ /dev/null @@ -1,9806 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -// #include -#include -#include "Decompiler.h" -#include "Main.h" -#include "Misc.h" -#include "TypeInfo.h" -#include "InputDlg.h" -// --------------------------------------------------------------------------- -extern int DelphiVersion; -extern MDisasm Disasm; -extern DWORD CodeBase; -extern DWORD CurProcAdr; -extern DWORD EP; -extern DWORD ImageBase; -extern BYTE *Image; -extern BYTE *Code; -extern PInfoRec *Infos; -extern TStringList *BSSInfos; -extern DWORD *Flags; -extern int VmtSelfPtr; -extern char StringBuf[MAXSTRBUFFER]; -extern MKnowledgeBase KnowledgeBase; - -// --------------------------------------------------------------------------- -String __fastcall GetString(PITEM item, BYTE precedence) { - String _val = item->Value; - - if (_val == "") { - if (item->Flags & IF_INTVAL) - return GetImmString(item->Type, item->IntValue); - if (item->Name != "") - _val = item->Name; - } - if (item->Precedence && item->Precedence < precedence) - return "(" + _val + ")"; - return _val; -} - -// --------------------------------------------------------------------------- -String __fastcall GetFieldName(PFIELDINFO fInfo) { - if (fInfo->Name == "") - return String("?f") + Val2Str0(fInfo->Offset); - return fInfo->Name; -} - -// --------------------------------------------------------------------------- -String __fastcall GetArgName(PARGINFO argInfo) { - if (argInfo->Name == "") - return String("arg_") + Val2Str0(argInfo->Ndx); - return argInfo->Name; -} - -// --------------------------------------------------------------------------- -String __fastcall GetGvarName(DWORD adr) { - if (!IsValidImageAdr(adr)) - return "?"; - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->HasName()) - return recN->GetName(); - return MakeGvarName(adr); -} -// --------------------------------------------------------------------------- -// 'A'-JO;'B'-JNO;'C'-JB;'D'-JNB;'E'-JZ;'F'-JNZ;'G'-JBE;'H'-JA; -// 'I'-JS;'J'-JNS;'K'-JP;'L'-JNP;'M'-JL;'N'-JGE;'O'-JLE;'P'-JG -// 'Q'-in;'R'-not in;'S'-is -String DirectConditions[19] = {"", "", "<", ">=", "=", "<>", "<=", ">", "", "", "", "", "<", ">=", "<=", ">", "not in", "in", "is"}; - -String __fastcall GetDirectCondition(char c) { - if (c >= 'A') - return DirectConditions[c - 'A']; - else - return "?"; -} -// --------------------------------------------------------------------------- -String InvertConditions[19] = {"", "", ">=", "<", "<>", "=", ">", "<=", "", "", "", "", ">=", "<", ">", "<=", "in", "not in", "is not"}; - -String __fastcall GetInvertCondition(char c) { - if (c >= 'A') - return InvertConditions[c - 'A']; - else - return "?"; -} - -// --------------------------------------------------------------------------- -void __fastcall InitItem(PITEM Item) { - Item->Flags = 0; - Item->Precedence = PRECEDENCE_ATOM; - Item->Size = 0; - Item->Offset = 0; - Item->IntValue = 0; - Item->Value = ""; - Item->Value1 = ""; - Item->Type = ""; - Item->Name = ""; -} - -// --------------------------------------------------------------------------- -void __fastcall AssignItem(PITEM DstItem, PITEM SrcItem) { - DstItem->Flags = SrcItem->Flags; - DstItem->Precedence = SrcItem->Precedence; - DstItem->Size = SrcItem->Size; - DstItem->IntValue = SrcItem->IntValue; - DstItem->Value = SrcItem->Value; - DstItem->Value1 = SrcItem->Value1; - DstItem->Type = SrcItem->Type; - DstItem->Name = SrcItem->Name; -} - -// --------------------------------------------------------------------------- -__fastcall TNamer::TNamer() { - MaxIdx = -1; - Names = new TStringList; - Names->Sorted = true; -} - -// --------------------------------------------------------------------------- -__fastcall TNamer::~TNamer() { - delete Names; -} - -// --------------------------------------------------------------------------- -String __fastcall TNamer::MakeName(String shablon) { - char name[1024]; - - if (shablon[1] == 'T') { - int idx = -1; - int len = sprintf(name, "_%s_", shablon.c_str() + 1); - for (int n = 0; n <= MaxIdx; n++) { - sprintf(name + len, "%d", n); - if (Names->IndexOf(String(name)) != -1) - idx = n; - } - if (idx == -1) { - Names->Add(String(name)); - if (MaxIdx == -1) - MaxIdx = 0; - } - else { - sprintf(name + len, "%d", idx + 1); - Names->Add(String(name)); - if (idx + 1 > MaxIdx) - MaxIdx = idx + 1; - } - } - return String(name); -} - -// --------------------------------------------------------------------------- -__fastcall TForInfo::TForInfo(bool ANoVar, bool ADown, int AStopAdr, String AFrom, String ATo, BYTE AVarType, int AVarIdx, BYTE ACntType, int ACntIdx) { - NoVar = ANoVar; - Down = ADown; - StopAdr = AStopAdr; - From = AFrom; - To = ATo; - VarInfo.IdxType = AVarType; - VarInfo.IdxValue = AVarIdx; - CntInfo.IdxType = ACntType; - CntInfo.IdxValue = ACntIdx; -} - -// --------------------------------------------------------------------------- -__fastcall TWhileInfo::TWhileInfo(bool ANoCond) { - NoCondition = ANoCond; -} - -// --------------------------------------------------------------------------- -__fastcall TLoopInfo::TLoopInfo(BYTE AKind, DWORD AContAdr, DWORD ABreakAdr, DWORD ALastAdr) { - Kind = AKind; - ContAdr = AContAdr; - BreakAdr = ABreakAdr; - LastAdr = ALastAdr; - forInfo = 0; - whileInfo = 0; -} - -// --------------------------------------------------------------------------- -__fastcall TLoopInfo::~TLoopInfo() { -} - -// --------------------------------------------------------------------------- -__fastcall TDecompileEnv::TDecompileEnv(DWORD AStartAdr, int ASize, PInfoRec recN) { - StartAdr = AStartAdr; - Size = ASize; - - StackSize = recN->procInfo->stackSize; - if (!StackSize) - StackSize = 0x8000; - Stack = new ITEM[StackSize]; - - ErrAdr = 0; - Body = new TStringList; - Namer = new TNamer; - SavedContext = new TList; - BJLseq = new TList; - bjllist = new TList; - CmpStack = new TList; - Embedded = (recN->procInfo->flags & PF_EMBED); - EmbeddedList = new TStringList; - - BpBased = recN->procInfo->flags & PF_BPBASED; - LocBase = 0; - if (!BpBased) - LocBase = StackSize; - LastResString = ""; -} - -// --------------------------------------------------------------------------- -__fastcall TDecompileEnv::~TDecompileEnv() { - if (Stack) - delete[]Stack; - if (Body) - delete Body; - if (Namer) - delete Namer; - if (SavedContext) - delete SavedContext; - if (BJLseq) - delete BJLseq; - if (bjllist) - delete bjllist; - if (CmpStack) - delete CmpStack; - if (EmbeddedList) - delete EmbeddedList; -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompileEnv::GetLvarName(int Ofs, String Type) { - PLOCALINFO locInfo; - String _defaultName = String("lvar_") + Val2Str0(LocBase - Ofs); - - // Insert by ZGL - PInfoRec _recN = GetInfoRec(StartAdr); - if (_recN && _recN->procInfo) { - if (_recN->procInfo->locals) { - for (int n = 0; n < _recN->procInfo->locals->Count; n++) { - locInfo = PLOCALINFO(_recN->procInfo->locals->Items[n]); - if (locInfo->Ofs == Ofs && locInfo->Name != "") // LocBase - Ofs - return locInfo->Name; - } - } - locInfo = _recN->procInfo->AddLocal(Ofs, 1, _defaultName, Type); - } - //////////////// - return _defaultName; -} - -// --------------------------------------------------------------------------- -PDCONTEXT __fastcall TDecompileEnv::GetContext(DWORD Adr) { - int n; - PDCONTEXT ctx; - - for (n = 0; n < SavedContext->Count; n++) { - ctx = (PDCONTEXT)SavedContext->Items[n]; - if (ctx->adr == Adr) - return ctx; - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::SaveContext(DWORD Adr) { - int n; - PDCONTEXT ctx; - - if (!GetContext(Adr)) { - ctx = new DCONTEXT; - ctx->adr = Adr; - - for (n = 0; n < 8; n++) { - ctx->gregs[n] = RegInfo[n]; - ctx->fregs[n] = FStack[n]; - } - SavedContext->Add((void*)ctx); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::RestoreContext(DWORD Adr) { - int n; - PDCONTEXT ctx; - - ctx = GetContext(Adr); - if (ctx) { - for (n = 0; n < 8; n++) { - RegInfo[n] = ctx->gregs[n]; - FStack[n] = ctx->fregs[n]; - } - } -} - -// --------------------------------------------------------------------------- -__fastcall TDecompiler::TDecompiler(TDecompileEnv* AEnv) { - WasRet = false; - Env = AEnv; - Stack = 0; - DeFlags = new BYTE[AEnv->Size + 1]; -} - -// --------------------------------------------------------------------------- -__fastcall TDecompiler::~TDecompiler() { - if (Stack) - delete[]Stack; - if (DeFlags) - delete DeFlags; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SetDeFlags(BYTE* ASrc) { - memmove(DeFlags, ASrc, Env->Size + 1); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SetStop(DWORD Adr) { - DeFlags[Adr - Env->StartAdr] = 1; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::InitFlags() { - memset(DeFlags, 0, Env->Size + 1); - int _ap = Adr2Pos(Env->StartAdr); - for (int n = _ap; n < _ap + Env->Size + 1; n++) { - if (IsFlagSet(cfLoc, n)) { - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN) - recN->counter = 0; - } - ClearFlag(cfPass, n); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::ClearStop(DWORD Adr) { - DeFlags[Adr - Env->StartAdr] = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SetStackPointers(TDecompiler* ASrc) { - _TOP_ = ASrc->_TOP_; - _ESP_ = ASrc->_ESP_; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SetRegItem(int Idx, PITEM Val) { - int _idx; - - if (Idx >= 16) { - _idx = Idx - 16; - Env->RegInfo[_idx].Size = 4; - } - else if (Idx >= 8) { - _idx = Idx - 8; - Env->RegInfo[_idx].Size = 2; - } - else if (Idx >= 4) { - _idx = Idx - 4; - Env->RegInfo[_idx].Size = 1; - } - else { - _idx = Idx; - Env->RegInfo[_idx].Size = 1; - } - - Env->RegInfo[_idx].Flags = Val->Flags; - Env->RegInfo[_idx].Precedence = Val->Precedence; - Env->RegInfo[_idx].Offset = Val->Offset; - Env->RegInfo[_idx].IntValue = Val->IntValue; - Env->RegInfo[_idx].Value = Val->Value; - Env->RegInfo[_idx].Value1 = Val->Value1; - Env->RegInfo[_idx].Type = Val->Type; - Env->RegInfo[_idx].Name = Val->Name; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::GetRegItem(int Idx, PITEM Dst) { - int _idx; - - assert(Idx >= 0 && Idx < 24); - - if (Idx >= 16) - _idx = Idx - 16; - else if (Idx >= 8) - _idx = Idx - 8; - else if (Idx >= 4) - _idx = Idx - 4; - else - _idx = Idx; - - PITEM _src = &Env->RegInfo[_idx]; - Dst->Flags = _src->Flags; - Dst->Precedence = _src->Precedence; - Dst->Size = _src->Size; - Dst->Offset = _src->Offset; - Dst->IntValue = _src->IntValue; - Dst->Value = _src->Value; - Dst->Value1 = _src->Value1; - Dst->Type = _src->Type; - Dst->Name = _src->Name; -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompiler::GetRegType(int Idx) { - if (Idx >= 16) - return Env->RegInfo[Idx - 16].Type; - if (Idx >= 8) - return Env->RegInfo[Idx - 8].Type; - if (Idx >= 4) - return Env->RegInfo[Idx - 4].Type; - return Env->RegInfo[Idx].Type; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::Push(PITEM Item) { - if (_ESP_ < 4) { - Env->ErrAdr = CurProcAdr; - throw Exception("Stack!"); - } - _ESP_ -= 4; - Env->Stack[_ESP_].Flags = Item->Flags; - Env->Stack[_ESP_].Precedence = Item->Precedence; - Env->Stack[_ESP_].Size = Item->Size; - Env->Stack[_ESP_].Offset = Item->Offset; - Env->Stack[_ESP_].IntValue = Item->IntValue; - Env->Stack[_ESP_].Value = Item->Value; - Env->Stack[_ESP_].Type = Item->Type; - Env->Stack[_ESP_].Name = Item->Name; -} - -// --------------------------------------------------------------------------- -PITEM __fastcall TDecompiler::Pop() { - if (_ESP_ == Env->StackSize) { - Env->ErrAdr = CurProcAdr; - throw Exception("Stack!"); - } - PITEM _item = &Env->Stack[_ESP_]; - _ESP_ += 4; - return _item; -} - -// --------------------------------------------------------------------------- -// Get val from ST(idx) -PITEM __fastcall TDecompiler::FGet(int idx) { - return &Env->FStack[(_TOP_ + idx) & 7]; -} - -// --------------------------------------------------------------------------- -// Save val into ST(idx) -void __fastcall TDecompiler::FSet(int idx, PITEM val) { - int n = (_TOP_ + idx) & 7; - Env->FStack[n].Flags = val->Flags; - Env->FStack[n].Precedence = val->Precedence; - Env->FStack[n].Size = val->Size; - Env->FStack[n].Offset = val->Offset; - Env->FStack[n].IntValue = val->IntValue; - Env->FStack[n].Value = val->Value; - Env->FStack[n].Type = val->Type; - Env->FStack[n].Name = val->Name; -} - -// --------------------------------------------------------------------------- -// Xchange ST(idx1) and ST(idx2) -void __fastcall TDecompiler::FXch(int idx1, int idx2) { - ITEM _tmp; - PITEM _item1 = FGet(idx1); - PITEM _item2 = FGet(idx2); - - _tmp.Flags = _item1->Flags; - _tmp.Precedence = _item1->Precedence; - _tmp.Size = _item1->Size; - _tmp.Offset = _item1->Offset; - _tmp.IntValue = _item1->IntValue; - _tmp.Value = _item1->Value; - _tmp.Type = _item1->Type; - _tmp.Name = _item1->Name; - - _item1->Flags = _item2->Flags; - _item1->Precedence = _item2->Precedence; - _item1->Size = _item2->Size; - _item1->Offset = _item2->Offset; - _item1->IntValue = _item2->IntValue; - _item1->Value = _item2->Value; - _item1->Type = _item2->Type; - _item1->Name = _item2->Name; - - _item2->Flags = _tmp.Flags; - _item2->Precedence = _tmp.Precedence; - _item2->Size = _tmp.Size; - _item2->Offset = _tmp.Offset; - _item2->IntValue = _tmp.IntValue; - _item2->Value = _tmp.Value; - _item2->Type = _tmp.Type; - _item2->Name = _tmp.Name; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::FPush(PITEM val) { - _TOP_--; - _TOP_ &= 7; - FSet(0, val); -} - -// --------------------------------------------------------------------------- -PITEM __fastcall TDecompiler::FPop() { - PITEM _item = FGet(0); - _TOP_++; - _TOP_ &= 7; - return _item; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompiler::CheckPrototype(PInfoRec ARec) { - int n, _argsNum; - PARGINFO _argInfo; - - _argsNum = (ARec->procInfo->args) ? ARec->procInfo->args->Count : 0; - for (n = 0; n < _argsNum; n++) { - _argInfo = (PARGINFO)ARec->procInfo->args->Items[n]; - if (_argInfo->TypeDef == "") - return false; - } - if (ARec->kind == ikFunc && ARec->type == "") - return false; - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompiler::Init(DWORD fromAdr) { - BYTE _kind, _retKind = 0, _callKind; - int n, _pos, _argsNum, _ndx, _rn, _size; - int _fromPos; - PInfoRec _recN, _recN1; - PARGINFO _argInfo; - ITEM _item; - String _retType, _typeDef; - - _fromPos = Adr2Pos(fromAdr); - assert(_fromPos >= 0); - // Imports not decompile - if (IsFlagSet(cfImport, _fromPos)) - return true; - _recN = GetInfoRec(fromAdr); - if (!CheckPrototype(_recN)) - return false; - _retType = _recN->type; - // Check that function return type is given - if (_recN->kind == ikFunc) - _retKind = GetTypeKind(_retType, &_size); - // Init registers - InitItem(&_item); - for (n = 16; n < 24; n++) { - SetRegItem(n, &_item); - } - - // Init Env->Stack - _ESP_ = Env->StackSize; - // Init floating registers stack - _TOP_ = 0; - for (n = 0; n < 8; n++) { - FSet(n, &_item); - } - - _callKind = _recN->procInfo->flags & 7; - - // Arguments - _argsNum = (_recN->procInfo->args) ? _recN->procInfo->args->Count : 0; - if (_callKind == 0) // fastcall - { - _ndx = 0; - for (n = 0; n < _argsNum; n++) { - _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; - InitItem(&_item); - _item.Flags = IF_ARG; - if (_argInfo->Tag == 0x22) - _item.Flags |= IF_VAR; - _kind = GetTypeKind(_argInfo->TypeDef, &_size); - _item.Type = _argInfo->TypeDef; - _item.Name = GetArgName(_argInfo); - _item.Value = _item.Name; - - if (_kind == ikFloat) { - _size = _argInfo->Size; - while (_size) { - Push(&_item); - _size -= 4; - } - continue; - } - // eax, edx, ecx - if (_ndx >= 0 && _ndx <= 2) { - if (_ndx) - _rn = 19 - _ndx; - else - _rn = 16; - - SetRegItem(_rn, &_item); - _ndx++; - } - else - Push(&_item); - } - // ret value - if (_retKind == ikLString || _retKind == ikRecord) { - InitItem(&_item); - _item.Flags = IF_ARG | IF_VAR; - _item.Type = _retType; - _item.Name = "Result"; - _item.Value = _item.Name; - - // eax, edx, ecx - if (_ndx >= 0 && _ndx <= 2) { - if (_ndx) - _rn = 19 - _ndx; - else - _rn = 16; - - SetRegItem(_rn, &_item); - _ndx++; - } - else - Push(&_item); - } - } - else if (_callKind == 3 || _callKind == 1) // stdcall, cdecl - { - // Arguments in reverse order - for (n = _argsNum - 1; n >= 0; n--) { - _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; - InitItem(&_item); - _item.Flags = IF_ARG; - if (_argInfo->Tag == 0x22) - _item.Flags |= IF_VAR; - _item.Type = _argInfo->TypeDef; - _item.Name = GetArgName(_argInfo); - _item.Value = _item.Name; - Push(&_item); - } - } - else if (_callKind == 2) // pascal - { - for (n = 0; n < _argsNum; n++) { - _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; - InitItem(&_item); - _item.Flags = IF_ARG; - if (_argInfo->Tag == 0x22) - _item.Flags |= IF_VAR; - _item.Type = _argInfo->TypeDef; - _item.Name = GetArgName(_argInfo); - _item.Value = _item.Name; - Push(&_item); - } - } - // Push ret address - InitItem(&_item); - Push(&_item); - // Env->BpBased = _recN->procInfo->flags & PF_BPBASED; - // Env->LocBase = 0; - // if (!Env->BpBased) Env->LocBase = _ESP_; - // Env->LastResString = ""; - return true; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::OutputSourceCodeLine(String line) { - int spaceNum = TAB_SIZE * Indent; - memset(StringBuf, ' ', spaceNum); - int len = sprintf(StringBuf + spaceNum, "%s", line.c_str()); - - FMain_11011981->lbSourceCode->Items->Add(String(StringBuf)); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::OutputSourceCode() { - bool _end; - String line, nextline; - - Alarm = False; - FMain_11011981->lbSourceCode->Clear(); - Indent = 0; - for (int n = 0; n < Body->Count; n++) { - line = Body->Strings[n]; - if (n < Body->Count - 1) - nextline = Body->Strings[n + 1]; - else - nextline = ""; - - if (line != "" && line[1] == '/' && line.Pos("??? And ???")) - Alarm = True; - - if (SameText(line, "begin") || SameText(line, "try") || SameText(line, "repeat") || line.Pos("case ") > 0) { - if (SameText(line, "begin")) - line += "//" + String(Indent); - OutputSourceCodeLine(line); - Indent++; - continue; - } - - if (SameText(line, "finally") || SameText(line, "except")) { - Indent--; - if (Indent < 0) - Indent = 0; - line += "//" + String(Indent); - OutputSourceCodeLine(line); - Indent++; - continue; - } - - if (SameText(line, "end") || SameText(line, "until")) { - _end = SameText(line, "end"); - Indent--; - if (Indent < 0) - Indent = 0; - if (!SameText(nextline, "else")) - line += ";"; - if (_end) - line += "//" + String(Indent); - OutputSourceCodeLine(line); - continue; - } - OutputSourceCodeLine(line); - } -} - -// --------------------------------------------------------------------------- -// Embedded??? -void __fastcall TDecompileEnv::DecompileProc() { - EmbeddedList->Clear(); - TDecompiler* De = new TDecompiler(this); - if (!De->Init(StartAdr)) { - De->Env->ErrAdr = StartAdr; - delete De; - throw Exception("Prototype is not completed"); - } - De->InitFlags(); - De->SetStop(StartAdr + Size); - - // add prototype - PInfoRec _recN = GetInfoRec(StartAdr); - ProcName = _recN->GetName(); - AddToBody(_recN->MakePrototype(StartAdr, true, false, false, true, false)); - - // add vars -- Insert by ZGL - if (_recN->procInfo->locals && _recN->procInfo->locals->Count > 0) { - for (int n = 0; n < _recN->procInfo->locals->Count; n++) { - PLOCALINFO locInfo = PLOCALINFO(_recN->procInfo->locals->Items[n]); - GetLvarName(locInfo->Ofs, locInfo->TypeDef); - } - } - if (_recN->procInfo->locals && _recN->procInfo->locals->Count > 0) { - AddToBody("var"); - for (int n = 0; n < _recN->procInfo->locals->Count; n++) { - PLOCALINFO locInfo = PLOCALINFO(_recN->procInfo->locals->Items[n]); - String line = " " + GetLvarName(locInfo->Ofs, locInfo->TypeDef) + ":" + locInfo->TypeDef + ";"; - AddToBody(line); - } - } - /////////////////////////// - - AddToBody("begin"); - if (StartAdr != EP) { - if (_recN->kind == ikConstructor) - De->Decompile(StartAdr, CF_CONSTRUCTOR, 0); - else if (_recN->kind == ikDestructor) - De->Decompile(StartAdr, CF_DESTRUCTOR, 0); - else - De->Decompile(StartAdr, 0, 0); - } - else { - De->Decompile(StartAdr, 0, 0); - } - AddToBody("end"); - delete De; -} - -// --------------------------------------------------------------------------- -// BJL -bool __fastcall TDecompileEnv::GetBJLRange(DWORD fromAdr, DWORD* bodyBegAdr, DWORD* bodyEndAdr, DWORD* jmpAdr, PLoopInfo loopInfo) { - BYTE _op; - int _curPos, _instrLen, _brType; - DWORD _curAdr, _jmpAdr; - DISINFO _disInfo; - - *bodyEndAdr = 0; - *jmpAdr = 0; - _curPos = Adr2Pos(fromAdr); - assert(_curPos >= 0); - _curAdr = fromAdr; - - while (1) { - if (_curAdr == *bodyBegAdr) - break; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - if (_disInfo.Branch) { - if (IsFlagSet(cfSkip, _curPos - _instrLen)) - continue; - if (!_disInfo.Conditional) - return false; - _brType = BranchGetPrevInstructionType(_disInfo.Immediate, &_jmpAdr, loopInfo); - // jcc down - if (_brType == 1) { - if (_disInfo.Immediate > *bodyBegAdr) { - *bodyBegAdr = _disInfo.Immediate; - continue; - } - } - // simple if or jmp down - if (_brType == 0 || _brType == 3) { - if (_disInfo.Immediate > *bodyEndAdr) { - *bodyEndAdr = _disInfo.Immediate; - if (_brType == 3) - * jmpAdr = _jmpAdr; - continue; - } - } - // jcc up - if (_brType == 2) { - // if (_disInfo.Immediate > fromAdr) return false; - if (*bodyEndAdr == 0) - * bodyEndAdr = _disInfo.Immediate; - else if (*bodyEndAdr != _disInfo.Immediate) - throw Exception("GetBJLRange: unknown situation"); - } - // jmp up - if (_brType == 4) - return false; - } - } - return true; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::CreateBJLSequence(DWORD fromAdr, DWORD bodyBegAdr, DWORD bodyEndAdr) { - bool found; - BYTE _b; - int i, j, m, _curPos, _instrLen; - DWORD _curAdr, _adr; - PInfoRec _recN; - TBJL *_bjl, *_bjl1, *_bjl2; - TBJLInfo *_bjlInfo, *_bjlInfo1, *_bjlInfo2; - DISINFO _disInfo; - - BJLnum = 0; - - bjllist->Clear(); - BJLseq->Clear(); - _curPos = Adr2Pos(fromAdr); - assert(_curPos >= 0); - _curAdr = fromAdr; - - while (1) { - if (_curAdr == bodyBegAdr) { - _bjl = new TBJL; - _bjl->branch = false; - _bjl->loc = true; - _bjl->type = BJL_LOC; - _bjl->address = bodyBegAdr; - _bjl->idx = 0; - bjllist->Add((void*)_bjl); - _bjlInfo = new TBJLInfo; - _bjlInfo->state = 'L'; - _bjlInfo->bcnt = 0; - _bjlInfo->address = bodyBegAdr; - _bjlInfo->dExpr = ""; - _bjlInfo->iExpr = ""; - BJLseq->Add((void*)_bjlInfo); - - _bjl = new TBJL; - _bjl->branch = false; - _bjl->loc = true; - _bjl->type = BJL_LOC; - _bjl->address = bodyEndAdr; - _bjl->idx = 0; - bjllist->Add((void*)_bjl); - _bjlInfo = new TBJLInfo; - _bjlInfo->state = 'L'; - _bjlInfo->bcnt = 0; - _bjlInfo->address = bodyEndAdr; - _bjlInfo->dExpr = ""; - _bjlInfo->iExpr = ""; - BJLseq->Add((void*)_bjlInfo); - break; - } - if (IsFlagSet(cfLoc, _curPos)) { - _bjl = new TBJL; - _bjl->branch = false; - _bjl->loc = true; - _bjl->type = BJL_LOC; - _bjl->address = _curAdr; - _bjl->idx = 0; - bjllist->Add((void*)_bjl); - _bjlInfo = new TBJLInfo; - _bjlInfo->state = 'L'; - _bjlInfo->bcnt = 0; - _bjlInfo->address = _curAdr; - _bjlInfo->dExpr = ""; - _bjlInfo->iExpr = ""; - BJLseq->Add((void*)_bjlInfo); - } - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - if (_disInfo.Branch) { - _bjl = new TBJL; - _bjl->branch = true; - _bjl->loc = false; - if (IsFlagSet(cfSkip, _curPos)) - _bjl->type = BJL_SKIP_BRANCH; - else - _bjl->type = BJL_BRANCH; - _bjl->address = _disInfo.Immediate; - _bjl->idx = 0; - bjllist->Add((void*)_bjl); - _bjlInfo = new TBJLInfo; - _bjlInfo->state = 'B'; - _bjlInfo->bcnt = 0; - _bjlInfo->address = _disInfo.Immediate; - - _b = *(Code + _curPos); - if (_b == 0xF) - _b = *(Code + _curPos + 1); - _bjlInfo->dExpr = GetDirectCondition((_b & 0xF) + 'A'); - _bjlInfo->iExpr = GetInvertCondition((_b & 0xF) + 'A'); - BJLseq->Add((void*)_bjlInfo); - } - _curPos += _instrLen; - _curAdr += _instrLen; - } - - for (i = 0, BJLmaxbcnt = 0; i < bjllist->Count; i++) { - _bjl1 = (TBJL*)bjllist->Items[i]; - if (_bjl1->type == BJL_BRANCH || _bjl1->type == BJL_SKIP_BRANCH) { - for (j = 0; j < bjllist->Count; j++) { - _bjl2 = (TBJL*)bjllist->Items[j]; - if (_bjl2->type == BJL_LOC && _bjl1->address == _bjl2->address) { - _bjlInfo = (TBJLInfo*)BJLseq->Items[j]; - _bjlInfo->bcnt++; - if (_bjlInfo->bcnt > BJLmaxbcnt) - BJLmaxbcnt = _bjlInfo->bcnt; - } - } - } - } - - while (1) { - found = false; - for (i = 0; i < bjllist->Count; i++) { - _bjl1 = (TBJL*)bjllist->Items[i]; - if (_bjl1->type == BJL_SKIP_BRANCH) { - _adr = _bjl1->address; - bjllist->Delete(i); - delete _bjl1; - - _bjlInfo1 = (TBJLInfo*)BJLseq->Items[i]; - BJLseq->Delete(i); - delete _bjlInfo1; - - for (j = 0; j < bjllist->Count; j++) { - _bjl2 = (TBJL*)bjllist->Items[j]; - if (_bjl2->type == BJL_LOC && _adr == _bjl2->address) { - _bjlInfo2 = (TBJLInfo*)BJLseq->Items[j]; - _bjlInfo2->bcnt--; - - if (!_bjlInfo2->bcnt) { - bjllist->Delete(j); - delete _bjl2; - BJLseq->Delete(j); - delete _bjlInfo2; - } - found = true; - break; - } - } - if (found) - break; - } - } - if (!found) - break; - } - - for (i = 0, m = 1, BJLmaxbcnt = 0; i < bjllist->Count; i++) { - _bjl1 = (TBJL*)bjllist->Items[i]; - _bjl1->idx = i; - if (_bjl1->type == BJL_BRANCH) { - _bjlInfo = (TBJLInfo*)BJLseq->Items[i]; - _bjlInfo->dExpr = "#" + String(m) + "#" + _bjlInfo->dExpr + "#" + String(m + 1) + "#"; - _bjlInfo->iExpr = "#" + String(m) + "#" + _bjlInfo->iExpr + "#" + String(m + 1) + "#"; - m += 2; - - for (j = 0; j < bjllist->Count; j++) { - _bjl2 = (TBJL*)bjllist->Items[j]; - if (_bjl2->type == BJL_LOC && _bjl1->address == _bjl2->address) { - _bjlInfo = (TBJLInfo*)BJLseq->Items[j]; - if (_bjlInfo->bcnt > BJLmaxbcnt) - BJLmaxbcnt = _bjlInfo->bcnt; - } - } - } - } - BJLnum = bjllist->Count; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::UpdateBJLList() { - bool found; - int i, j; - TBJL *_bjl, *_bjl1, *_bjl2; - TBJLInfo *_bjlInfo; - - while (1) { - found = false; - for (i = 0; i < bjllist->Count; i++) { - _bjl = (TBJL*)bjllist->Items[i]; - if (_bjl->type == BJL_USED) { - bjllist->Delete(i); - found = true; - break; - } - } - if (!found) - break; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::BJLAnalyze() { - bool found = true; - int i, j, k, indx, no; - TBJL *_bjl; - TBJLInfo *_bjlInfo; - String sd, si; - int idx[MAXSEQNUM]; - char pattern[MAXSEQNUM]; - - UpdateBJLList(); - - while (found) { - found = false; - // BM BM ... BM <=> BM (|| ... ||) - // BM 0 - // BM 1 - // ... - // BM k-1 - for (k = BJLmaxbcnt; k >= 2; k--) { - for (i = 0; i < bjllist->Count; i++) { - if (!BJLGetIdx(idx, i, k)) - continue; - for (j = 0; j < k; j++) - pattern[j] = 'B'; - pattern[k] = 0; - if (!BJLCheckPattern1(pattern, i)) - continue; - for (j = 0; j < k; j++) - pattern[j] = '1'; - pattern[k] = 0; - if (!BJLCheckPattern2(pattern, i)) - continue; - _bjl = (TBJL*)bjllist->Items[i]; - if ((indx = BJLFindLabel(_bjl->address, &no)) == -1) - continue; - - BJLSeqSetStateU(idx, k - 1); - BJLListSetUsed(i, k - 1); - sd = ""; - si = ""; - - for (j = 0; j < k; j++) { - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[j]]; - ExprMerge(sd, _bjlInfo->dExpr, '|'); - ExprMerge(si, _bjlInfo->iExpr, '&'); - } - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[k - 1]]; - _bjlInfo->dExpr = sd; - _bjlInfo->iExpr = si; - - _bjlInfo = (TBJLInfo*)BJLseq->Items[indx]; - _bjl = (TBJL*)bjllist->Items[no]; - _bjlInfo->bcnt -= k - 1; - if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) - _bjl->type = BJL_USED; - - UpdateBJLList(); - found = true; - break; - } - if (found) - break; - } - if (found) - continue; - // BN BM @N <=> BM (&&) - // BN 0 - // BM 1 - // @N 2 - for (i = 0; i < bjllist->Count; i++) { - if (!BJLGetIdx(idx, i, 3)) - continue; - if (!BJLCheckPattern1("BBL", i)) - continue; - if (!BJLCheckPattern2("101", i)) - continue; - if (BJLCheckPattern2("111", i)) - continue; // check that N != M - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; - _bjlInfo->state = 'U'; - _bjl = (TBJL*)bjllist->Items[i]; - _bjl->type = BJL_USED; - - sd = ""; - si = ""; - ExprMerge(sd, _bjlInfo->iExpr, '&'); - ExprMerge(si, _bjlInfo->dExpr, '|'); - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[1]]; - ExprMerge(sd, _bjlInfo->dExpr, '&'); - ExprMerge(si, _bjlInfo->iExpr, '|'); - - _bjlInfo->dExpr = sd; - _bjlInfo->iExpr = si; - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[2]]; - _bjl = (TBJL*)bjllist->Items[i + 2]; - _bjlInfo->bcnt--; - if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) - _bjl->type = BJL_USED; - - UpdateBJLList(); - found = true; - break; - } - if (found) - continue; - // BN @N <=> if (~BN) - // BN 0 if { - // @N 1 } - for (i = 0; i < bjllist->Count; i++) { - if (!BJLGetIdx(idx, i, 2)) - continue; - if (!BJLCheckPattern1("BL", i)) - continue; - if (!BJLCheckPattern2("11", i)) - continue; - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; - _bjlInfo->state = 'I'; - _bjlInfo->result = _bjlInfo->iExpr; - _bjl = (TBJL*)bjllist->Items[i]; - _bjl->branch = false; - _bjl->type = BJL_USED; - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[1]]; - _bjl = (TBJL*)bjllist->Items[i + 1]; - _bjlInfo->bcnt--; - if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) - _bjl->type = BJL_USED; - - UpdateBJLList(); - found = true; - break; - } - if (found) - continue; - // BN BM @N @M <=> if (BN || ~BM) - // BN 0 if { - // BM 1 - // @N 2 - // @M 3 } k = 1 - for (i = 0; i < bjllist->Count; i++) { - if (!BJLGetIdx(idx, i, 4)) - continue; - if (!BJLCheckPattern1("BBLL", i)) - continue; - if (!BJLCheckPattern2("1010", i)) - continue; - if (!BJLCheckPattern2("0101", i)) - continue; - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; - _bjlInfo->state = 'I'; - sd = _bjlInfo->dExpr; - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[1]]; - ExprMerge(sd, _bjlInfo->iExpr, '|'); - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[0]]; - _bjlInfo->result = sd; - - BJLSeqSetStateU(idx, 2); - BJLListSetUsed(i, 2); - - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[2]]; - _bjl = (TBJL*)bjllist->Items[i + 2]; - _bjlInfo->bcnt--; - if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) - _bjl->type = BJL_USED; - _bjl = (TBJL*)bjllist->Items[i + 3]; - _bjlInfo->bcnt--; - if (!_bjlInfo->bcnt && _bjl->type == BJL_LOC) - _bjl->type = BJL_USED; - - UpdateBJLList(); - found = true; - break; - } - if (found) - continue; - } -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompileEnv::BJLGetIdx(int* idx, int from, int num) { - TBJL *_bjl; - - for (int k = 0; k < num; k++) { - if (from + k < bjllist->Count) { - _bjl = (TBJL*)bjllist->Items[from + k]; - idx[k] = _bjl->idx; - } - else { - return false; - } - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompileEnv::BJLCheckPattern1(char* t, int from) { - TBJL *_bjl; - - for (int k = 0; k < strlen(t); k++) { - if (from + k >= bjllist->Count) - return false; - _bjl = (TBJL*)bjllist->Items[from + k]; - if (t[k] == 'B' && !_bjl->branch) - return false; - if (t[k] == 'L' && !_bjl->loc) - return false; - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompileEnv::BJLCheckPattern2(char* t, int from) { - int _address = -1; - TBJL *_bjl; - - for (int k = 0; k < strlen(t); k++) { - if (from + k >= bjllist->Count) - return false; - if (t[k] == '1') { - _bjl = (TBJL*)bjllist->Items[from + k]; - if (_address == -1) { - _address = _bjl->address; - continue; - } - if (_bjl->address != _address) - return false; - } - } - return true; -} - -// --------------------------------------------------------------------------- -int __fastcall TDecompileEnv::BJLFindLabel(int address, int* no) { - TBJL *_bjl; - - *no = -1; - for (int k = 0; k < bjllist->Count; k++) { - _bjl = (TBJL*)bjllist->Items[k]; - if (_bjl->loc && _bjl->address == address) { - *no = k; - return _bjl->idx; - } - } - return -1; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::BJLSeqSetStateU(int* idx, int num) { - TBJLInfo *_bjlInfo; - - for (int k = 0; k < num; k++) { - if (idx[k] < 0 || idx[k] >= BJLseq->Count) - break; - _bjlInfo = (TBJLInfo*)BJLseq->Items[idx[k]]; - _bjlInfo->state = 'U'; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::BJLListSetUsed(int from, int num) { - TBJL *_bjl; - - for (int k = 0; k < num; k++) { - if (from + k >= bjllist->Count) - break; - _bjl = (TBJL*)bjllist->Items[from + k]; - _bjl->type = BJL_USED; - } -} - -// --------------------------------------------------------------------------- -char __fastcall TDecompileEnv::ExprGetOperation(String s) { - char c; - int n = 0; - - for (int k = 1; k <= s.Length(); k++) { - c = s[k]; - if (c == '(') { - n++; - continue; - } - if (c == ')') { - n--; - continue; - } - if ((c == '&' || c == '|') && !n) - return c; - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::ExprMerge(String& dst, String src, char op) // dst = dst op src, op = '|' or '&' -{ - char op1, op2; - - if (dst == "") { - dst = src; - return; - } - - op1 = ExprGetOperation(dst); - op2 = ExprGetOperation(src); - - if (op == '|') { - if (op1 == 0) { - if (op2 == 0) { - dst = dst + " || " + src; - return; - } - if (op2 == '|') { - dst = dst + " || " + src; - return; - } - if (op2 == '&') { - dst = dst + " || (" + src + ")"; - return; - } - } - if (op1 == '|') { - if (op2 == 0) { - dst = dst + " || " + src; - return; - } - if (op2 == '|') { - dst = dst + " || " + src; - return; - } - if (op2 == '&') { - dst = dst + " || (" + src + ")"; - return; - } - } - if (op1 == '&') { - if (op2 == 0) { - dst = "(" + dst + ") || " + src; - return; - } - if (op2 == '|') { - dst = "(" + dst + ") || " + src; - return; - } - if (op2 == '&') { - dst = "(" + dst + ") || (" + src + ")"; - return; - } - } - } - if (op == '&') { - if (op1 == 0) { - if (op2 == 0) { - dst = dst + " && " + src; - return; - } - if (op2 == '|') { - dst = dst + " && (" + src + ")"; - return; - } - if (op2 == '&') { - dst = dst + " && " + src; - return; - } - } - if (op1 == '|') { - if (op2 == 0) { - dst = "(" + dst + ") && " + src; - return; - } - if (op2 == '|') { - dst = "(" + dst + ") && (" + src + ")"; - return; - } - if (op2 == '&') { - dst = "(" + dst + ") && " + src; - return; - } - } - if (op1 == '&') { - if (op2 == 0) { - dst = dst + " && " + src; - return; - } - if (op2 == '|') { - dst = dst + " && (" + src + ")"; - return; - } - if (op2 == '&') { - dst = dst + " && " + src; - return; - } - } - } -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompileEnv::PrintBJL() { - int n, m, k; - String _result = ""; - CMPITEM *_cmpItem; - TBJLInfo *_bjlInfo; - - for (n = 0; n < BJLseq->Count; n++) { - _bjlInfo = (TBJLInfo*)BJLseq->Items[n]; - if (_bjlInfo->state == 'I') { - _result = _bjlInfo->result; - for (m = 0, k = 1; m < CmpStack->Count; m++) { - _cmpItem = (CMPITEM*)CmpStack->Items[m]; - _result = AnsiReplaceText(_result, "#" + String(k) + "#", "(" + _cmpItem->L + " "); - k++; - _result = AnsiReplaceText(_result, "#" + String(k) + "#", " " + _cmpItem->R + ")"); - k++; - } - break; - } - } - _result = AnsiReplaceText(_result, "||", "Or"); - _result = AnsiReplaceText(_result, "&&", "And"); - return _result; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall TDecompiler::Decompile(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo) { - bool _cmp, _immInt64Val, _fullSim; - BYTE _op; - DWORD _dd, _curAdr, _branchAdr, _sAdr, _jmpAdr, _endAdr, _adr; - DWORD _begAdr; - int n, _kind, _skip1, _skip2, _size, _elSize, _procSize; - int _fromPos, _curPos, _endPos, _instrLen, _instrLen1, _num, _regIdx, _pos, _sPos; - int _decPos, _cmpRes, _varidx, _brType, _mod, _div; - int _bytesToSkip, _bytesToSkip1, _bytesToSkip2, _bytesToSkip3; - __int64 _int64Val; - PInfoRec _recN, _recN1; - PLoopInfo _loopInfo; - PXrefRec _recX; - ITEM _item, _item1, _item2; - String _line, _comment, _name, _typeName; - DISINFO _disInfo; - TDecompiler *de; - - _fromPos = Adr2Pos(fromAdr); - - _line = "//" + Val2Str8(fromAdr); - if (IsFlagSet(cfPass, _fromPos)) { - _line += "??? And ???"; - // return fromAdr; - } - Env->AddToBody(_line); - - _curPos = _fromPos; - _curAdr = fromAdr; - _procSize = GetProcSize(Env->StartAdr); - - while (1) { - // !!! - if (_curAdr == 0x00698056) - _curAdr = _curAdr; - // End of decompilation - if (DeFlags[_curAdr - Env->StartAdr] == 1) { - SetFlag(cfPass, _fromPos); - break; - } - // @TryFinallyExit - if (IsFlagSet(cfFinallyExit, _curPos)) { - Env->AddToBody("Exit;"); - while (IsFlagSet(cfFinallyExit, _curPos)) { - _curPos++; - _curAdr++; - } - continue; - } - // Try - if (IsFlagSet(cfTry, _curPos)) { - try { - _curAdr = DecompileTry(_curAdr, flags, loopInfo); - } - catch (Exception &exception) { - throw Exception("Decompile->" + exception.Message); - } - _curPos = Adr2Pos(_curAdr); - continue; - } - - if (IsFlagSet(cfLoop, _curPos)) { - _recN = GetInfoRec(_curAdr); - if (IsFlagSet(cfFrame, _curPos)) { - if (_recN && _recN->xrefs->Count == 1) { - _recX = (PXrefRec)_recN->xrefs->Items[0]; - _endPos = GetNearestUpInstruction(Adr2Pos(_recX->adr + _recX->offset)); - _endAdr = Pos2Adr(_endPos); - // Check instructions between _curAdr and _endAdr (must be push, add or sub to full simulation) - _fullSim = true; - _pos = _curPos; - _adr = _curAdr; - while (1) { - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op != OP_PUSH && _op != OP_ADD && _op != OP_SUB) { - _fullSim = false; - break; - } - _pos += _instrLen; - _adr += _instrLen; - if (_pos >= _endPos) - break; - } - // Full simulation - if (_fullSim) { - // Get instruction at _endAdr - _pos = _endPos; - _adr = _endAdr; - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // dec reg in frame - full simulate - if (_op == OP_DEC && _disInfo.OpType[0] == otREG) { - _regIdx = _disInfo.OpRegIdx[0]; - GetRegItem(_regIdx, &_item); - // Save dec position - _decPos = _pos; - - _num = _item.IntValue; - // next instruction is jne - _pos += _instrLen; - _adr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - _branchAdr = _disInfo.Immediate; - // Save position and address - _sPos = _pos + _instrLen; - _sAdr = _adr + _instrLen; - - for (n = 0; n < _num; n++) { - _adr = _branchAdr; - _pos = Adr2Pos(_adr); - while (1) { - if (_pos == _decPos) - break; - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &DisInfo, 0); - _op = Disasm.GetOp(DisInfo.Mnem); - if (_op == OP_PUSH) - SimulatePush(_adr, true); - if (_op == OP_ADD || _op == OP_SUB) - SimulateInstr2(_adr, _op); - _pos += _instrLen; - _adr += _instrLen; - } - } - // reg = 0 after cycle - InitItem(&_item); - _item.Flags |= IF_INTVAL; - SetRegItem(_regIdx, &_item); - _curPos = _sPos; - _curAdr = _sAdr; - continue; - } - } - } - } - else // loop - { - // Count xrefs from above - for (n = 0, _num = 0; n < _recN->xrefs->Count; n++) { - _recX = (PXrefRec)_recN->xrefs->Items[n]; - if (_recX->adr + _recX->offset < _curAdr) - _num++; - } - if (_recN && _recN->counter < _recN->xrefs->Count - _num) { - _recN->counter++; - _loopInfo = GetLoopInfo(_curAdr); - if (!_loopInfo) { - Env->ErrAdr = _curAdr; - throw Exception("Control flow under construction"); - } - // for - if (_loopInfo->Kind == 'F') { - _line = "for "; - if (_loopInfo->forInfo->NoVar) { - _varidx = _loopInfo->forInfo->CntInfo.IdxValue; - // register - if (_loopInfo->forInfo->CntInfo.IdxType == itREG) - _line += GetDecompilerRegisterName(_varidx); - // local var - if (_loopInfo->forInfo->CntInfo.IdxType == itLVAR) - _line += Env->GetLvarName((int)_varidx, "Integer"); - } - else { - _varidx = _loopInfo->forInfo->VarInfo.IdxValue; - // register - if (_loopInfo->forInfo->VarInfo.IdxType == itREG) - _line += GetDecompilerRegisterName(_varidx); - // local var - if (_loopInfo->forInfo->VarInfo.IdxType == itLVAR) - _line += Env->GetLvarName((int)_varidx, "Integer"); - } - _line += " := " + _loopInfo->forInfo->From + " "; - if (_loopInfo->forInfo->Down) - _line += "down"; - _line += "to " + _loopInfo->forInfo->To + " do"; - Env->AddToBody(_line); - - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(_loopInfo->forInfo->StopAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_curAdr, 0, _loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("Loop->" + exception.Message); - } - delete de; - if (_curAdr > _loopInfo->BreakAdr) { - Env->ErrAdr = _curAdr; - throw Exception("Loop->desynchronization"); - } - _curAdr = _loopInfo->BreakAdr; - _curPos = Adr2Pos(_curAdr); - delete _loopInfo; - continue; - } - // while, repeat - else { - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(_loopInfo->BreakAdr); - try { - if (_loopInfo->Kind == 'R') - Env->AddToBody("repeat"); - else { - Env->AddToBody("while () do"); - Env->AddToBody("begin"); - } - _curAdr = de->Decompile(_curAdr, 0, _loopInfo); - if (_loopInfo->Kind == 'R') - Env->AddToBody("until"); - else - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("Loop->" + exception.Message); - } - delete de; - if (_curAdr > _loopInfo->BreakAdr) { - Env->ErrAdr = _curAdr; - throw Exception("Loop->desynchronization"); - } - _curAdr = _loopInfo->BreakAdr; - _curPos = Adr2Pos(_curAdr); - delete _loopInfo; - continue; - } - } - } - } - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - // if (!_instrLen) - // { - // Env->ErrAdr = _curAdr; - // throw Exception("Unknown instruction"); - // } - if (!_instrLen) { - Env->AddToBody("???"); - _curPos++; - _curAdr++; - continue; - } - - if (IsFlagSet(cfDSkip, _curPos)) { - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - _dd = *((DWORD*)DisInfo.Mnem); - // skip wait, sahf - if (_dd == 'tiaw' || _dd == 'fhas') { - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - _op = Disasm.GetOp(DisInfo.Mnem); - // cfSkip - skip instructions - if (IsFlagSet(cfSkip, _curPos)) { - // Constructor or Destructor - if ((_op == OP_TEST || _op == OP_CMP || DisInfo.Call) && (flags & (CF_CONSTRUCTOR | CF_DESTRUCTOR))) { - while (1) { - // If instruction test or cmp - skip until loc (instruction at loc position need to be executed) - if ((_op == OP_TEST || _op == OP_CMP) && IsFlagSet(cfLoc, _curPos)) - break; - _curPos += _instrLen; - _curAdr += _instrLen; - // Skip @BeforeDestruction - if (DisInfo.Call && !IsFlagSet(cfSkip, _curPos)) - break; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - if (!_instrLen) { - Env->AddToBody("???"); - _curPos++; - _curAdr++; - continue; - } - } - continue; - } - if ((flags & (CF_FINALLY | CF_EXCEPT))) { - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (DisInfo.Call) { - if (flags & CF_EXCEPT) { - _recN = GetInfoRec(DisInfo.Immediate); - if (_recN->SameName("@DoneExcept")) { - _curPos += _instrLen; - _curAdr += _instrLen; - break; - } - } - } - } - - if (DisInfo.Branch) { - _pos = Adr2Pos(DisInfo.Immediate); - if (DisInfo.Conditional) { - _bytesToSkip = IsIntOver(_curAdr); - if (_bytesToSkip) { - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - // Skip jns - if (_dd == 'snj') { - _curAdr = DisInfo.Immediate; - _curPos = Adr2Pos(_curAdr); - continue; - } - } - // skip jmp - else { - // Case without cmp - if (IsFlagSet(cfSwitch, _curPos)) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileCaseEnum(_curAdr, 0, loopInfo); - Env->AddToBody("end"); - _curPos = Adr2Pos(_curAdr); - continue; - } - // Some deoptimization! - if (0) // IsFlagSet(cfLoop, _pos) - { - _recN = GetInfoRec(DisInfo.Immediate); - if (_recN->xrefs) { - for (n = 0; n < _recN->xrefs->Count; n++) { - _recX = (PXrefRec)_recN->xrefs->Items[n]; - if (_recX->adr + _recX->offset == _curAdr && _recX->type == 'J') { - SetFlag(cfLoop | cfLoc, _curPos); - _recN1 = GetInfoRec(_curAdr); - if (!_recN1) - _recN1 = new InfoRec(_curPos, ikUnknown); - continue; - } - } - } - } - // jmp XXXXXXXX - End Of Decompilation? - if (DeFlags[DisInfo.Immediate - Env->StartAdr] == 1) { - // SetFlag(cfPass, _fromPos); - // check Exit - if (IsExit(DisInfo.Immediate)) - Env->AddToBody("Exit;"); - _curPos += _instrLen; - _curAdr += _instrLen; - break; - } - _curPos += _instrLen; - _curAdr += _instrLen; - if (DeFlags[_curAdr - Env->StartAdr] == 1) { - // if stop flag at this point - check Exit - if (IsExit(DisInfo.Immediate)) - Env->AddToBody("Exit;"); - // if jmp BreakAdr - if (loopInfo && loopInfo->BreakAdr == DisInfo.Immediate) - Env->AddToBody("Break;"); - } - continue; - } - } - - if (DisInfo.Call) { - _recN = GetInfoRec(DisInfo.Immediate); - if (_recN) { - // Inherited - if ((flags & (CF_CONSTRUCTOR | CF_DESTRUCTOR)) && IsValidCodeAdr(DisInfo.Immediate)) { - GetRegItem(16, &_item); - if (SameText(_item.Value, "Self")) // eax=Self - { - if (_recN->kind == ikConstructor || _recN->kind == ikDestructor) { - SimulateInherited(DisInfo.Immediate); - Env->AddToBody("inherited;"); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - } - // Other case (not constructor and destructor) - if (IsInheritsByProcName(Env->ProcName, _recN->GetName())) { - SimulateInherited(DisInfo.Immediate); - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Name = "EAX"; - _item.Type = _recN->type; - SetRegItem(16, &_item); - Env->AddToBody("EAX := inherited " + ExtractProcName(Env->ProcName) + ";"); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - // true - CMP - _cmp = SimulateCall(_curAdr, DisInfo.Immediate, _instrLen, 0, 0); - if (_cmp) { - _sPos = _curPos; - _sAdr = _curAdr; - _curPos += _instrLen; - _curAdr += _instrLen; - _cmpRes = GetCmpInfo(_curAdr); - CmpInfo.O = CmpOp; - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; // ??? - } - - if (_cmpRes == CMP_BRANCH) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - // jcc up - if (_disInfo.Immediate < _curAdr) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - - if (_op == OP_MOV) { - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (DisInfo.Ret) { - _ESP_ += 4; - _curPos += _instrLen; - _curAdr += _instrLen; - // End of proc - if (_procSize && _curPos - _fromPos < _procSize) - Env->AddToBody("Exit;"); - WasRet = true; - SetFlag(cfPass, Adr2Pos(fromAdr)); - break; - // continue; - } - if (_op == OP_PUSH) { - _bytesToSkip1 = IsInt64ComparisonViaStack1(_curAdr, &_skip1, &_endAdr); - _bytesToSkip2 = IsInt64ComparisonViaStack2(_curAdr, &_skip1, &_skip2, &_endAdr); - if (_bytesToSkip1 + _bytesToSkip2 == 0) { - SimulatePush(_curAdr, !IsFlagSet(cfFrame, _curPos)); - _curPos += _instrLen; - _curAdr += _instrLen; - } - else { - // Save position and address - _sPos = _curPos; - _sAdr = _curAdr; - - // Simulate push - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulatePush(_curAdr, true); - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulatePush(_curAdr, true); - _curPos += _instrLen; - _curAdr += _instrLen; - - // Decompile until _skip1 - SetStop(_endAdr); - Decompile(_curAdr, flags, 0); - - if (_bytesToSkip1) - _cmpRes = GetCmpInfo(_sAdr + _bytesToSkip1); - else - _cmpRes = GetCmpInfo(_sAdr + _bytesToSkip2); - - // Simulate 2nd cmp instruction - _curPos = _sPos + _skip1; - _curAdr = _sAdr + _skip1; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr2(_curAdr, OP_CMP); - _curPos += _instrLen; - _curAdr += _instrLen; - // Simulate pop - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulatePop(_curAdr); - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulatePop(_curAdr); - - if (_bytesToSkip1) { - _curPos = _sPos + _bytesToSkip1; - _curAdr = _sAdr + _bytesToSkip1; - } - else { - _curPos = _sPos + _bytesToSkip2; - _curAdr = _sAdr + _bytesToSkip2; - } - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_cmpRes == CMP_BRANCH) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - // jcc up - if (_disInfo.Immediate < _curAdr) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - } - } - continue; - } - if (_op == OP_POP) { - SimulatePop(_curAdr); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_XOR) { - if (!IsXorMayBeSkipped(_curAdr)) - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_CMP || (DisInfo.Float && _dd == 'mocf')) { - // Save position and address - _sPos = _curPos; - _sAdr = _curAdr; - _bytesToSkip = IsBoundErr(_curAdr); - if (_bytesToSkip) { - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - if (IsFlagSet(cfSwitch, _curPos)) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileCaseEnum(_curAdr, 0, loopInfo); - Env->AddToBody("end"); - _curPos = Adr2Pos(_curAdr); - continue; - } - _bytesToSkip = IsInlineLengthCmp(_curAdr); - if (_bytesToSkip) { - GetMemItem(_curAdr, &_item, 0); - _line = _item.Name + " := Length("; - if (_item.Name != "") - _line += _item.Name; - else - _line += _item.Value; - _line += ");"; - Env->AddToBody(_line); - - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); - if (_endAdr) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); - Env->AddToBody("end"); - // _curAdr = _endAdr; - _curPos = Adr2Pos(_curAdr); - continue; - } - // skip current instruction (cmp) - _curPos += _instrLen; - _curAdr += _instrLen; - - if (!DisInfo.Float) { - _bytesToSkip1 = 0; // IsInt64Equality(_sAdr, &_skip1, &_skip2, &_immInt64Val, &_int64Val); - _bytesToSkip2 = 0; // IsInt64NotEquality(_sAdr, &_skip1, &_skip2, &_immInt64Val, &_int64Val); - _bytesToSkip3 = IsInt64Comparison(_sAdr, &_skip1, &_skip2, &_immInt64Val, &_int64Val); - if (_bytesToSkip1 + _bytesToSkip2 + _bytesToSkip3 == 0) { - _cmpRes = GetCmpInfo(_curAdr); - SimulateInstr2(_sAdr, _op); - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - // int64 comparison - else { - if (_bytesToSkip1) { - _cmpRes = GetCmpInfo(_sAdr + _skip2); - _curPos = _sPos + _skip1; - _curAdr = _sAdr + _skip1; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr2(_curAdr, _op); - if (_immInt64Val) - CmpInfo.R = IntToStr(_int64Val) + "{" + IntToHex(_int64Val, 0) + "}"; - _curPos = _sPos + _bytesToSkip1; - _curAdr = _sAdr + _bytesToSkip1; - } - else if (_bytesToSkip2) { - _cmpRes = GetCmpInfo(_sAdr + _skip2); - _curPos = _sPos + _skip1; - _curAdr = _sAdr + _skip1; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr2(_curAdr, _op); - if (_immInt64Val) - CmpInfo.R = IntToStr(_int64Val) + "{" + IntToHex(_int64Val, 0) + "}"; - _curPos = _sPos + _bytesToSkip2; - _curAdr = _sAdr + _bytesToSkip2; - } - else // _bytesToSkip3 - { - _cmpRes = GetCmpInfo(_sAdr + _skip2); - _curPos = _sPos + _skip1; - _curAdr = _sAdr + _skip1; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr2(_curAdr, _op); - if (_immInt64Val) - CmpInfo.R = IntToStr(_int64Val) + "{" + IntToHex(_int64Val, 0) + "}"; - _curPos = _sPos + _bytesToSkip3; - _curAdr = _sAdr + _bytesToSkip3; - } - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - } - else { - // skip until branch or set - while (1) { - _instrLen1 = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_disInfo.Branch || _op == OP_SET) - break; - _curPos += _instrLen1; - _curAdr += _instrLen1; - } - - _cmpRes = GetCmpInfo(_curAdr); - SimulateFloatInstruction(_sAdr, _instrLen); - - if (flags & CF_BJL) { - // SimulateFloatInstruction(_sAdr, _instrLen); - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - _curPos += _instrLen1; - _curAdr += _instrLen1; - continue; - } - } - if (_cmpRes == CMP_FAILED) - continue; - - if (_cmpRes == CMP_BRANCH) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - // Exit - if (IsExit(_disInfo.Immediate)) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Exit;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - // jcc up - if (_disInfo.Immediate < _curAdr) { - // if (DisInfo.Float) SimulateFloatInstruction(_sAdr, _instrLen); - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - // jcc at BreakAdr - if (loopInfo && loopInfo->BreakAdr == _disInfo.Immediate) { - // if (DisInfo.Float) SimulateFloatInstruction(_sAdr, _instrLen); - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Break;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - // jcc at forInfo->StopAdr - if (loopInfo && loopInfo->forInfo && loopInfo->forInfo->StopAdr == _disInfo.Immediate) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - if (_op == OP_TEST || _op == OP_BT) { - // Save address - _sAdr = _curAdr; - _bytesToSkip = IsInlineLengthTest(_curAdr); - if (_bytesToSkip) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "Length(" + _item.Value + ")"; - _item.Type = "Integer"; - SetRegItem(DisInfo.OpRegIdx[0], &_item); - - _line = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " := Length(" + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + ");"; - Env->AddToBody(_line); - - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - _bytesToSkip = IsInlineDiv(_curAdr, &_div); - if (_bytesToSkip) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(&_item, PRECEDENCE_MULT) + " Div " + String(_div); - _item.Type = "Integer"; - SetRegItem(DisInfo.OpRegIdx[0], &_item); - - _line = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " := " + _item.Value + ";"; - Env->AddToBody(_line); - - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - - _cmpRes = GetCmpInfo(_curAdr + _instrLen); - SimulateInstr2(_sAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - - if (_cmpRes == CMP_BRANCH) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - // jcc up - if (_disInfo.Immediate < _curAdr) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - // jcc at BreakAdr - if (loopInfo && loopInfo->BreakAdr == _disInfo.Immediate) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Break;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - // jcc at forInfo->StopAdr - if (loopInfo && loopInfo->forInfo && loopInfo->forInfo->StopAdr == _disInfo.Immediate) { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Continue;"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - if (_op == OP_LEA) { - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_ADD) { - _bytesToSkip = IsIntOver(_curAdr + _instrLen); - - _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); - if (_endAdr) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); - Env->AddToBody("end"); - // _curAdr = _endAdr; - _curPos = Adr2Pos(_curAdr); - continue; - } - // Next switch - if (IsFlagSet(cfSwitch, _curPos + _instrLen)) { - n = -DisInfo.Immediate; - _curPos += _instrLen; - _curAdr += _instrLen; - Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - GetRegItem(_disInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(_disInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileCaseEnum(_curAdr, n, loopInfo); - Env->AddToBody("end"); - _curPos = Adr2Pos(_curAdr); - continue; - } - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen + _bytesToSkip; - _curAdr += _instrLen + _bytesToSkip; - continue; - } - if (_op == OP_SUB) { - // Save address - _sAdr = _curAdr; - _bytesToSkip = IsIntOver(_curAdr + _instrLen); - - _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); - if (_endAdr) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); - Env->AddToBody("end"); - // _curAdr = _endAdr; - _curPos = Adr2Pos(_curAdr); - continue; - } - // Next switch - if (IsFlagSet(cfSwitch, _curPos + _instrLen)) { - n = DisInfo.Immediate; - _curPos += _instrLen; - _curAdr += _instrLen; - Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - GetRegItem(_disInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(_disInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileCaseEnum(_curAdr, n, loopInfo); - Env->AddToBody("end"); - _curPos = Adr2Pos(_curAdr); - continue; - } - _cmpRes = GetCmpInfo(_curAdr + _instrLen); - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - - if (_bytesToSkip) { - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - - if (_cmpRes == CMP_BRANCH) { - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - continue; - } - if (_op == OP_AND) { - _bytesToSkip = IsInlineMod(_curAdr, &_mod); - if (_bytesToSkip) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = _item.Value + " mod " + String(_mod); - _item.Type = "Integer"; - SetRegItem(DisInfo.OpRegIdx[0], &_item); - - _line = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " := " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " mod " + String(_mod); - Env->AddToBody(_line); - - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - _cmpRes = GetCmpInfo(_curAdr + _instrLen); - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_cmpRes == CMP_BRANCH) { - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - continue; - } - if (_op == OP_OR) { - _cmpRes = GetCmpInfo(_curAdr + _instrLen); - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_cmpRes == CMP_BRANCH) { - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - continue; - } - if (_op == OP_ADC || _op == OP_SBB) { - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_SAL || _op == OP_SHL) { - _bytesToSkip = IsInt64Shl(_curAdr); - if (_bytesToSkip) { - DisInfo.OpNum = 2; - DisInfo.OpType[1] = otIMM; - } - else { - _bytesToSkip = _instrLen; - } - SimulateInstr2(_curAdr, _op); - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - if (_op == OP_SAR || _op == OP_SHR) { - _bytesToSkip = IsInt64Shr(_curAdr); - if (_bytesToSkip) { - DisInfo.OpNum = 2; - DisInfo.OpType[1] = otIMM; - } - else { - _bytesToSkip = _instrLen; - } - SimulateInstr2(_curAdr, _op); - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - continue; - } - if (_op == OP_NEG) { - SimulateInstr1(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_NOT) { - SimulateInstr1(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_XCHG) { - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_op == OP_INC || _op == OP_DEC) { - // Save address - _sAdr = _curAdr; - _endAdr = IsGeneralCase(_curAdr, Env->StartAdr + Env->Size); - if (_endAdr) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - if (_item.Value != "") - Env->AddToBody("case " + _item.Value + " of"); - else - Env->AddToBody("case " + GetDecompilerRegisterName(DisInfo.OpRegIdx[0]) + " of"); - _curAdr = DecompileGeneralCase(_curAdr, _curAdr, loopInfo, 0); - Env->AddToBody("end"); - // _curAdr = _endAdr; - _curPos = Adr2Pos(_curAdr); - continue; - } - // simulate dec as sub - DisInfo.OpNum = 2; - DisInfo.OpType[1] = otIMM; - DisInfo.Immediate = 1; - _cmpRes = GetCmpInfo(_curAdr + _instrLen); - if (_op == OP_DEC) - SimulateInstr2(_curAdr, OP_SUB); - else - SimulateInstr2(_curAdr, OP_ADD); - _curPos += _instrLen; - _curAdr += _instrLen; - - if (_cmpRes == CMP_FAILED) - continue; - - if (flags & CF_BJL) { - CMPITEM* _cmpItem = new CMPITEM; - _cmpItem->L = CmpInfo.L; - _cmpItem->O = CmpInfo.O; - _cmpItem->R = CmpInfo.R; - Env->CmpStack->Add((void*)_cmpItem); - // skip jcc - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - - if (_cmpRes == CMP_BRANCH) { - _brType = BranchGetPrevInstructionType(CmpAdr, &_jmpAdr, loopInfo); - // Skip conditional branch - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, 0, 0); - _curAdr += _instrLen; - - _curAdr = AnalyzeConditions(_brType, _curAdr, _sAdr, _jmpAdr, loopInfo); - _curPos = Adr2Pos(_curAdr); - continue; - } - if (_cmpRes == CMP_SET) { - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &DisInfo, 0); - SimulateInstr1(_curAdr, Disasm.GetOp(DisInfo.Mnem)); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - continue; - } - if (_op == OP_DIV || _op == OP_IDIV) { - if (DisInfo.OpNum == 2) { - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - } - if (_op == OP_MUL || _op == OP_IMUL) { - _bytesToSkip = IsIntOver(_curAdr + _instrLen); - - if (DisInfo.OpNum == 1) { - SimulateInstr1(_curAdr, _op); - _curPos += _instrLen + _bytesToSkip; - _curAdr += _instrLen + _bytesToSkip; - continue; - } - if (DisInfo.OpNum == 2) { - SimulateInstr2(_curAdr, _op); - _curPos += _instrLen + _bytesToSkip; - _curAdr += _instrLen + _bytesToSkip; - continue; - } - if (DisInfo.OpNum == 3) { - SimulateInstr3(_curAdr, _op); - _curPos += _instrLen + _bytesToSkip; - _curAdr += _instrLen + _bytesToSkip; - continue; - } - } - if (_op == OP_CDQ) { - _curPos += _instrLen; - _curAdr += _instrLen; - GetRegItem(16, &_item); - _bytesToSkip = IsAbs(_curAdr); - if (_bytesToSkip) { - _item.Flags = IF_CALL_RESULT; - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "Abs(" + _item.Value + ")"; - _item.Type = "Integer"; - SetRegItem(16, &_item); - - _line = "EAX := Abs(EAX)"; - _comment = _item.Value; - Env->AddToBody(_line + ";//" + _comment); - - _curPos += _bytesToSkip; - _curAdr += _bytesToSkip; - } - SetRegItem(18, &_item); // Set edx to eax - continue; - } - if (_op == OP_MOVS) { - GetRegItem(23, &_item1); // edi - GetRegItem(22, &_item2); // esi - // ->lvar - if (_item1.Flags & IF_STACK_PTR) { - if (_item1.Type != "") - _typeName = _item1.Type; - else - _typeName = _item2.Type; - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _size = GetRecordSize(_typeName); - for (int r = 0; r < _size; r++) { - if (_item1.IntValue + r >= Env->StackSize) { - Env->ErrAdr = _curAdr; - throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); - } - _item = Env->Stack[_item1.IntValue + r]; - _item.Flags = IF_FIELD; - _item.Offset = r; - _item.Type = ""; - if (r == 0) - _item.Type = _typeName; - Env->Stack[_item1.IntValue + r] = _item; - } - } - else if (_kind == ikArray) { - _size = GetArraySize(_typeName); - _elSize = GetArrayElementTypeSize(_typeName); - _typeName = GetArrayElementType(_typeName); - if (!_size || !_elSize) { - Env->ErrAdr = _curAdr; - throw Exception("Possibly incorrect array definition"); - } - for (int r = 0; r < _size; r += _elSize) { - if (_item1.IntValue + r >= Env->StackSize) { - Env->ErrAdr = _curAdr; - throw Exception("Possibly incorrect array definition"); - } - Env->Stack[_item1.IntValue + r].Type = _typeName; - } - } - Env->AddToBody(Env->GetLvarName(_item1.IntValue, _typeName) + " := " + _item2.Value + ";"); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - // lvar-> - if (_item2.Flags & IF_STACK_PTR) { - if (_item2.Type != "") - _typeName = _item2.Type; - else - _typeName = _item1.Type; - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _size = GetRecordSize(_typeName); - for (int r = 0; r < _size; r++) { - if (_item2.IntValue + r >= Env->StackSize) { - Env->ErrAdr = _curAdr; - throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); - } - _item = Env->Stack[_item2.IntValue + r]; - _item.Flags = IF_FIELD; - _item.Offset = r; - _item.Type = ""; - if (r == 0) - _item.Type = _typeName; - Env->Stack[_item2.IntValue + r] = _item; - } - } - else if (_kind == ikArray) { - _size = GetArraySize(_typeName); - _elSize = GetArrayElementTypeSize(_typeName); - _typeName = GetArrayElementType(_typeName); - if (!_size || !_elSize) { - Env->ErrAdr = _curAdr; - throw Exception("Possibly incorrect array definition"); - } - for (int r = 0; r < _size; r += _elSize) { - if (_item1.IntValue + r >= Env->StackSize) { - Env->ErrAdr = _curAdr; - throw Exception("Possibly incorrect array definition"); - } - Env->Stack[_item1.IntValue + r].Type = _typeName; - } - } - Env->AddToBody(_item1.Value + " := " + Env->GetLvarName(_item2.IntValue, _typeName) + ";"); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (_item1.Value != "") - _line = _item1.Value; - else - _line = "_edi_"; - _line += " := "; - if (_item2.Value != "") - _line += _item2.Value; - else - _line += "_esi_"; - _line += ";"; - Env->AddToBody(_line); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - if (DisInfo.Float) { - SimulateFloatInstruction(_curAdr, _instrLen); - _curPos += _instrLen; - _curAdr += _instrLen; - continue; - } - - Env->ErrAdr = _curAdr; - throw Exception("Still unknown"); - } - return _curAdr; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateInherited(DWORD procAdr) { - PInfoRec _recN = GetInfoRec(procAdr); - _ESP_ += _recN->procInfo->retBytes; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompiler::SimulateCall(DWORD curAdr, DWORD callAdr, int instrLen, PMethodRec recM, DWORD AClassAdr) { - bool _sep, _fromKB, _vmt; - BYTE _kind, _callKind, _retKind, _methodKind, *p, *pp; - int _res = 0; - int _argsNum, _retBytes, _retBytesCalc, _len, _val, _esp; - int _idx = -1, _rn, _ndx, ss, _pos, _size, _recsize; - WORD* _uses; - DWORD _classAdr, _adr, _dynAdr, _vmtAdr; - char *tmpBuf; - ITEM _item, _item1; - ARGINFO _aInfo, *_argInfo = &_aInfo; - PFIELDINFO _fInfo; - MProcInfo _pInfo; - PMethodRec _recM; - PInfoRec _recN, _recN1; - MTypeInfo _tInfo; - TDecompiler *de; - String _name, _type, _alias, _line, _retType, _value, _iname, _embAdr; - String _typeName, _comment, _regName, _propName, _lvarName; - - pp = 0; - ss = 0; - _propName = ""; - // call imm - if (IsValidCodeAdr(callAdr)) { - _recN = GetInfoRec(callAdr); - _name = _recN->GetName(); - // Is it property function (Set, Get, Stored)? - if (_name.Pos(".")) { - _propName = KnowledgeBase.IsPropFunction(ExtractClassName(_name), ExtractProcName(_name)); - } - if (SameText(_name, "@AbstractError")) { - Env->ErrAdr = curAdr; - throw Exception("Pure Virtual Call"); - } - // Import can have no prototype - if (IsFlagSet(cfImport, Adr2Pos(callAdr))) { - if (!CheckPrototype(_recN)) { - Env->AddToBody(_recN->GetName() + "(...);//Import"); - _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%lX", &_retBytes); - _ESP_ += _retBytes; - return false; - } - } - // @DispInvoke - if (SameText(_name, "@DispInvoke")) { - Env->AddToBody("DispInvoke(...);"); - _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%lX", &_retBytes); - _ESP_ += _retBytes; - return false; - } - if (!recM) { - _name = _recN->GetName(); - _callKind = _recN->procInfo->flags & 7; - _methodKind = _recN->kind; - _argsNum = (_recN->procInfo->args) ? _recN->procInfo->args->Count : 0; - _retType = _recN->type; - _fromKB = (_recN->kbIdx != -1); - _retBytes = _recN->procInfo->retBytes; - // stdcall, pascal, cdecl - return bytes = 4 * ArgsNum - if ((_callKind == 3 || _callKind == 2 || _callKind == 1) && !_retBytes) - _retBytes = _argsNum * 4; - if (_recN->procInfo->flags & PF_EMBED) { - _embAdr = Val2Str8(callAdr); - if (Env->EmbeddedList->IndexOf(_embAdr) == -1) { - Env->EmbeddedList->Add(_embAdr); - int _savedIdx = FMain_11011981->lbCode->ItemIndex; - FMain_11011981->lbCode->ItemIndex = -1; - if (Application->MessageBox(String("Decompile embedded procedure at address " + _embAdr + "?").c_str(), L"Confirmation", MB_YESNO) == IDYES) { - Env->AddToBody("//BEGIN_EMBEDDED_" + _embAdr); - Env->AddToBody(_recN->MakePrototype(callAdr, true, false, false, true, false)); - DWORD _savedStartAdr = Env->StartAdr; - bool _savedBpBased = Env->BpBased; - int _savedLocBase = Env->LocBase; - int _savedSize = Env->Size; - Env->StartAdr = callAdr; - _size = GetProcSize(callAdr); - Env->Size = _size; - de = new TDecompiler(Env); - _ESP_ -= 4; // ret address - de->SetStackPointers(this); - de->SetStop(callAdr + _size); - try { - Env->AddToBody("begin"); - de->Decompile(callAdr, 0, 0); - Env->AddToBody("end"); - Env->AddToBody("//END_EMBEDDED_" + _embAdr); - } - catch (Exception &exception) { - delete de; - throw Exception("Embedded->" + exception.Message); - } - _ESP_ += 4; - delete de; - Env->StartAdr = _savedStartAdr; - Env->Size = _savedSize; - Env->BpBased = _savedBpBased; - Env->LocBase = _savedLocBase; - } - FMain_11011981->lbCode->ItemIndex = _savedIdx; - } - } - } - else { - _name = recM->name; - _res = (int)KnowledgeBase.GetProcInfo(AnsiString(recM->name).c_str(), INFO_DUMP | INFO_ARGS, &_pInfo, &_idx); - if (_res && _res != -1) { - _callKind = _pInfo.CallKind; - switch (_pInfo.MethodKind) { - case 'C': - _methodKind = ikConstructor; - break; - case 'D': - _methodKind = ikDestructor; - break; - case 'F': - _methodKind = ikFunc; - break; - case 'P': - _methodKind = ikProc; - break; - } - _argsNum = (_pInfo.Args) ? _pInfo.ArgsNum : 0; - _retType = _pInfo.TypeDef; - pp = _pInfo.Args; - _fromKB = true; - _retBytes = GetProcRetBytes(&_pInfo); - } - else { - _name = _recN->GetName(); - _callKind = _recN->procInfo->flags & 7; - _methodKind = _recN->kind; - _argsNum = (_recN->procInfo->args) ? _recN->procInfo->args->Count : 0; - _retType = _recN->type; - _fromKB = false; - _retBytes = _recN->procInfo->retBytes; - } - } - // Check prototype - if (!_fromKB) { - if (!CheckPrototype(_recN)) { - Env->ErrAdr = curAdr; - if (_name != "") - throw Exception("Prototype of " + _name + " is not completed"); - else - throw Exception("Prototype of " + GetDefaultProcName(callAdr) + " is not completed"); - } - } - if (_name != "") { - if (_name[1] == '@') { - if (SameText(_name, "@CallDynaInst") || SameText(_name, "@CallDynaClass")) { - _recN = GetInfoRec(curAdr); - if (_recN) { - PICODE* _picode = _recN->picode; - if (_picode && _picode->Op == OP_CALL) { - SimulateCall(curAdr, _picode->Ofs.Address, instrLen, 0, 0); - return false; - } - } - else { - GetRegItem(16, &_item); - if (DelphiVersion <= 5) { - GetRegItem(11, &_item1); - _comment = GetDynaInfo(GetClassAdr(_item.Type), _item1.IntValue, &_dynAdr); // bx - } - else { - GetRegItem(14, &_item1); - _comment = GetDynaInfo(GetClassAdr(_item.Type), _item1.IntValue, &_dynAdr); // si - } - AddPicode(Adr2Pos(curAdr), OP_CALL, _comment, _dynAdr); - SimulateCall(curAdr, _dynAdr, instrLen, 0, 0); - return false; - } - } - _alias = GetSysCallAlias(_name); - if (_alias == "") { - return SimulateSysCall(_name, curAdr, instrLen); - } - _name = _alias; - } - // Some special functions - if (SameText(_name, "Format")) { - SimulateFormatCall(); - return false; - } - if (_name.Pos(".")) { - _line = ExtractProcName(_name); - } - else - _line = _name; - } - else - _line = GetDefaultProcName(callAdr); - - if (_propName != "") - _line += "{" + _propName + "}"; - - if (_methodKind == ikFunc) { - while (1) { - if (_retType == "") - _retKind = 0; - else { - if (_retType[1] == '^') - _retType = GetTypeDeref(_retType); - _retKind = GetTypeKind(_retType, &_size); - } - if (_retKind) - break; - _retType = ManualInput(Env->StartAdr, curAdr, "Define type of function at " + IntToHex((int)curAdr, 8), "Type:"); - if (_retType == "") { - Env->ErrAdr = curAdr; - throw Exception("You need to define type of function later"); - } - } - } - - _retBytesCalc = 0; - _ndx = 0; - if (_argsNum) { - _line += "("; - if (_callKind == 0 || _callKind == 3 || _callKind == 2 || _callKind == 1) // fastcall, stdcall, pascal, cdecl - { - _sep = false; - _esp = _ESP_; - _ESP_ += _retBytes; - // fastcall, pascal - reverse order of arguments - if (_callKind == 0 || _callKind == 2) - _esp = _ESP_; - // cdecl - stack restored by caller - if (_callKind == 1) - _ESP_ -= _retBytes; - - for (int n = 0; n < _argsNum; n++) { - if (pp) - FillArgInfo(n, _callKind, _argInfo, &pp, &ss); - else - _argInfo = (PARGINFO)_recN->procInfo->args->Items[n]; - - _rn = -1; - _regName = ""; - _kind = GetTypeKind(_argInfo->TypeDef, &_size); - if (_argInfo->Tag == 0x22 || _argInfo->Tag == 0x23) - _size = 4; - if (_kind == ikFloat) - _size = _argInfo->Size; - - if (_callKind == 0) // fastcall - { - if (_methodKind == ikConstructor) { - if (_ndx <= 1) { - if (!_ndx) { - GetRegItem(16, &_item); - _retType = _item.Type; - _retKind = GetTypeKind(_retType, &_size); - _line = _retType + ".Create("; - } - _ndx++; - continue; - } - } - if (_kind == ikFloat) { - _esp -= _size; - _item = Env->Stack[_esp]; - _item1 = Env->Stack[_esp + 4]; - _retBytesCalc += _size; - } - else { - // fastcall - if (_ndx >= 0 && _ndx <= 2) { - // eax - if (_ndx == 0) { - _rn = 16; - _regName = "EAX"; - } - // edx - else if (_ndx == 1) { - _rn = 18; - _regName = "EDX"; - } - // ecx - else { - _rn = 17; - _regName = "ECX"; - } - GetRegItem(_rn, &_item); - _ndx++; - } - // stack args - else { - _esp -= _argInfo->Size; - _item = Env->Stack[_esp]; - _retBytesCalc += _argInfo->Size; - } - } - } - else if (_callKind == 3 || _callKind == 1) // stdcall, cdecl - { - if (_size >= 8) { - _item = Env->Stack[_esp]; - _item1 = Env->Stack[_esp + 4]; - _esp += _size; - _retBytesCalc += _size; - } - else { - _item = Env->Stack[_esp]; - _esp += _argInfo->Size; - _retBytesCalc += _argInfo->Size; - } - } - if (SameText(_argInfo->Name, "Self")) { - if (!SameText(_item.Value, "Self")) - _line = _item.Value + "." + _line; - _sep = false; - continue; - } - if (SameText(_argInfo->Name, "_Dv__")) { - _sep = false; - continue; - } - if (_sep) - _line += ", "; - _sep = true; - if (_item.Flags & IF_STACK_PTR) { - _item1 = Env->Stack[_item.IntValue]; - if (_kind == ikInteger) { - _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); - _line += _lvarName; - Env->Stack[_item.IntValue].Value = _lvarName; - continue; - } - if (_kind == ikEnumeration) { - _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); - _line += _lvarName; - Env->Stack[_item.IntValue].Value = _lvarName; - continue; - } - if (_kind == ikLString || _kind == ikVariant) { - _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); - _line += _lvarName; - Env->Stack[_item.IntValue].Value = _lvarName; ; - Env->Stack[_item.IntValue].Type = _argInfo->TypeDef; - continue; - } - if (_kind == ikVMT || _kind == ikClass) { - _line += _item1.Value; - continue; - } - if (_kind == ikArray) { - _line += Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); - continue; - } - if (_kind == ikRecord) { - _line += Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); - _recsize = GetRecordSize(_argInfo->TypeDef); - for (int r = 0; r < _recsize; r++) { - if (_item.IntValue + r >= Env->StackSize) { - Env->ErrAdr = curAdr; - throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); - } - _item1 = Env->Stack[_item.IntValue + r]; - _item1.Flags = IF_FIELD; - _item1.Offset = r; - _item1.Type = ""; - if (r == 0) - _item1.Type = _argInfo->TypeDef; - Env->Stack[_item.IntValue + r] = _item1; - } - continue; - } - // Type not found - _lvarName = Env->GetLvarName(_item.IntValue, _argInfo->TypeDef); - _line += _lvarName; - Env->Stack[_item.IntValue].Value = _lvarName; - Env->Stack[_item.IntValue].Type = _argInfo->TypeDef; - continue; - } - if (_kind == ikInteger) { - _line += _item.Value; - if (_item.Flags & IF_INTVAL) - _line += "{" + GetImmString(_item.IntValue) + "}"; - continue; - } - if (_kind == ikChar) { - _line += _item.Value; - if (_item.Flags & IF_INTVAL) - _line += "{'" + String(_item.IntValue) + "'}"; - continue; - } - if (_kind == ikLString || _kind == ikWString || _kind == ikUString || _kind == ikCString || _kind == ikWCString) { - if (_item.Value != "") - _line += _item.Value; - else { - if (_item.Flags & IF_INTVAL) { - if (!_item.IntValue) - _line += "''"; - else { - _recN1 = GetInfoRec(_item.IntValue); - if (_recN1) - _line += _recN1->GetName(); - else { - if (_kind == ikCString) { - _line += "'" + String((char*)(Code + Adr2Pos(_item.IntValue))) + "'"; - } - else if (_kind == ikLString) - _line += TransformString((char*)(Code + Adr2Pos(_item.IntValue)), -1); - else - _line += TransformUString(CP_ACP, (wchar_t*)(Code + Adr2Pos(_item.IntValue)), -1); - } - } - } - } - continue; - } - if (_kind == ikVMT || _kind == ikClass) { - if (_item.Value != "") - _line += _item.Value; - else { - if ((_item.Flags & IF_INTVAL) && (!_item.IntValue)) - _line += "Nil"; - else - _line += "?"; - } - continue; - } - if (_kind == ikEnumeration) { - if (_rn != -1) - _line += _regName + "{"; - if (_item.Flags & IF_INTVAL) { - _line += GetEnumerationString(_argInfo->TypeDef, _item.IntValue); - } - else if (_item.Value != "") { - _line += _item.Value; - } - if (_rn != -1) - _line += "}"; - continue; - } - if (_kind == ikSet) { - if (_item.Flags & IF_INTVAL) { - if (IsValidImageAdr(_item.IntValue)) - _line += GetSetString(_argInfo->TypeDef, Code + Adr2Pos(_item.IntValue)); - else - _line += GetSetString(_argInfo->TypeDef, (BYTE*)&_item.IntValue); - } - else - _line += _item.Value; - continue; - } - if (_kind == ikRecord) { - if (_size < 8) - _line += _item.Value; - else - _line += _item1.Value; - continue; - } - if (_kind == ikFloat) { - if (_item.Flags & IF_INTVAL) { - GetFloatItemFromStack(_esp, &_item, FloatNameToFloatType(_argInfo->TypeDef)); - _line += _item.Value; - } - else - _line += _item.Value; - continue; - } - if (_kind == ikClassRef) { - _line += _item.Type; - continue; - } - if (_kind == ikResString) { - _line += _item.Value; - continue; - } - if (_kind == ikPointer) { - if ((_item.Flags & IF_INTVAL) && IsValidImageAdr(_item.IntValue)) { - _recN1 = GetInfoRec(_item.IntValue); - if (_recN1 && _recN1->HasName()) - _line += _recN1->GetName(); - else - _line += "sub_" + Val2Str8(_item.IntValue); - continue; - } - } - // var - if (_argInfo->Tag == 0x22) { - _adr = _item.IntValue; - if (IsValidImageAdr(_adr)) { - _recN1 = GetInfoRec(_adr); - if (_recN1 && _recN1->HasName()) - _line += _recN1->GetName(); - else - _line += MakeGvarName(_adr); - } - else - _line += _item.Value; - continue; - } - if (_argInfo->Size == 8) { - if (SameText(_item1.Value, "Self")) { - if ((_item.Flags & IF_INTVAL) && IsValidImageAdr(_item.IntValue)) { - _recN1 = GetInfoRec(_item.IntValue); - if (_recN1 && _recN1->HasName()) - _line += _recN1->GetName(); - else - _line += "sub_" + Val2Str8(_item.IntValue); - continue; - } - } - _line += _item.Value; - continue; - } - if (_item.Value != "") - _line += _item.Value; - else if (_item.Flags & IF_INTVAL) - _line += String(_item.IntValue); - else - _line += "?"; - continue; - } - } - _len = _line.Length(); - if (_line[_len] != '(') - _line += ")"; - else - _line.SetLength(_len - 1); - } - if (_methodKind != ikFunc && _methodKind != ikConstructor) { - _line += ";"; - if (Env->LastResString != "") { - _line += "//" + QuotedStr(Env->LastResString); - Env->LastResString = ""; - } - Env->AddToBody(_line); - } - else { - if (_callKind == 0) // fastcall - { - if (_retKind == ikLString || _retKind == ikUString || _retKind == ikRecord || _retKind == ikVariant || _retKind == ikArray) { - // eax - if (_ndx == 0) - GetRegItem(16, &_item); - // edx - else if (_ndx == 1) - GetRegItem(18, &_item); - // ecx - else if (_ndx == 2) - GetRegItem(17, &_item); - // last pushed - else { - _esp -= 4; - _item = Env->Stack[_esp]; - } - - if (_item.Flags & IF_STACK_PTR) { - if (_item.Name != "") - _line = _item.Name + " := " + _line; - else if (_item.Value != "") - _line = _item.Value + " := " + _line; - else - _line = Env->GetLvarName(_item.IntValue, _retType) + " := " + _line; - if (_retKind == ikRecord) { - _size = GetRecordSize(_retType); - for (int r = 0; r < _size; r++) { - if (_item.IntValue + r >= Env->StackSize) { - Env->ErrAdr = curAdr; - throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); - } - _item1 = Env->Stack[_item.IntValue + r]; - _item1.Flags = IF_FIELD; - _item1.Offset = r; - _item1.Type = ""; - if (r == 0) - _item1.Type = _retType; - Env->Stack[_item.IntValue + r] = _item1; - } - } - Env->Stack[_item.IntValue].Flags = 0; - Env->Stack[_item.IntValue].Type = _retType; - } - else - _line = _item.Value + " := " + _line; - - _line += ";"; - if (Env->LastResString != "") { - _line += "//" + QuotedStr(Env->LastResString); - Env->LastResString = ""; - } - Env->AddToBody(_line); - } - else if (_retKind == ikFloat) { - InitItem(&_item); - _item.Value = _line; - _item.Type = _retType; - FPush(&_item); - } - else { - // ???__int64 - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Flags = IF_CALL_RESULT; - _item.Value = _line; - _item.Type = _retType; - SetRegItem(16, &_item); - _line += ";"; - if (Env->LastResString != "") { - _line += "//" + QuotedStr(Env->LastResString); - Env->LastResString = ""; - } - Env->AddToBody("EAX := " + _line); - } - } - else if (_callKind == 3 || _callKind == 1) // stdcall, cdecl - { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Flags = IF_CALL_RESULT; - _item.Value = _line; - _item.Type = _retType; - SetRegItem(16, &_item); - _line += ";"; - Env->AddToBody("EAX := " + _line); - } - } - if (_callKind == 3 && _retBytesCalc != _retBytes) { - Env->ErrAdr = curAdr; - throw Exception("Incorrect number of return bytes!"); - } - // _ESP_ += _retBytes; - return false; - } - // call [reg+N] - if (DisInfo.BaseReg != -1) { - // esp - if (DisInfo.BaseReg == 20) { - _item = Env->Stack[_ESP_ + DisInfo.Offset]; - _line = Env->GetLvarName(_ESP_ + DisInfo.Offset, "") + "(...);"; - Env->AddToBody(_line); - _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%lX", &_retBytes); - _ESP_ += _retBytes; - return false; - } - - GetRegItem(DisInfo.BaseReg, &_item); - _classAdr = 0; - // if (SameText(_item.Value, "Self")) - // { - // Env->ErrAdr = curAdr; - // throw Exception("Under construction"); - // } - if (_item.Type != "") - _classAdr = GetClassAdr(_item.Type); - if (_item.Flags & IF_VMT_ADR) - _classAdr = _item.IntValue; - if (IsValidImageAdr(_classAdr)) { - // Interface - if (_item.Flags & IF_INTERFACE) { - Env->AddToBody(_item.Value + ".I" + String(DisInfo.Offset) + "(...);"); - _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%lX", &_retBytes); - _ESP_ += _retBytes; - return false; - } - // Method - _recM = FMain_11011981->GetMethodInfo(_classAdr, 'V', DisInfo.Offset); - if (_recM) { - callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - VmtSelfPtr + DisInfo.Offset)); - if (_recM->abstract) { - _classAdr = GetChildAdr(_classAdr); - callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - VmtSelfPtr + DisInfo.Offset)); - } - if (_recM->name != "") - return SimulateCall(curAdr, callAdr, instrLen, _recM, _classAdr); - else - return SimulateCall(curAdr, callAdr, instrLen, 0, _classAdr); - } - // Field - if (!FMain_11011981->GetField(_item.Type, DisInfo.Offset, _name, _type)) { - while (!_recM) { - _typeName = ManualInput(CurProcAdr, curAdr, "Class " + _item.Type + " has no such virtual method. Give correct class name", "Name:"); - if (_typeName == "") { - Env->ErrAdr = curAdr; - throw Exception("Possibly incorrect class (has no such virtual method)"); - } - _classAdr = GetClassAdr(_typeName); - _recM = FMain_11011981->GetMethodInfo(_classAdr, 'V', DisInfo.Offset); - } - callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - VmtSelfPtr + DisInfo.Offset)); - if (_recM->abstract) { - _classAdr = GetChildAdr(_classAdr); - callAdr = *((DWORD*)(Code + Adr2Pos(_classAdr) - VmtSelfPtr + DisInfo.Offset)); - } - if (_recM->name != "") - return SimulateCall(curAdr, callAdr, instrLen, _recM, _classAdr); - else - return SimulateCall(curAdr, callAdr, instrLen, 0, _classAdr); - } - else { - if (_name != "") - Env->AddToBody(_name + "(...);"); - else - Env->AddToBody("f" + Val2Str0(DisInfo.Offset) + "(...);"); - _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%lX", &_retBytes); - _ESP_ += _retBytes; - return false; - } - } - if (_item.Flags & IF_STACK_PTR) { - _item = Env->Stack[_item.IntValue + DisInfo.Offset]; - _line = _item.Value + ";"; - Env->AddToBody(_line); - _value = ManualInput(CurProcAdr, curAdr, "Input return bytes number (in hex) of procedure at " + Val2Str8(curAdr), "Bytes:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%lX", &_retBytes); - _ESP_ += _retBytes; - return false; - } - } - // call reg - if (DisInfo.OpNum == 1 && DisInfo.OpType[0] == otREG) { - // GetRegItem(DisInfo.OpRegIdx[0], &_item); - // _line = _item.Value + ";"; - Env->AddToBody("call...;"); - _value = ManualInput(CurProcAdr, curAdr, "Input stack arguments number of procedure at " + Val2Str8(curAdr), "ArgsNum:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%d", &_argsNum); - _ESP_ += _argsNum * 4; - return false; - } - // call [reg+N] - if (DisInfo.OpNum == 1 && DisInfo.OpType[0] == otMEM) { - Env->AddToBody("call("); - _value = ManualInput(CurProcAdr, curAdr, "Input stack arguments number of procedure at " + Val2Str8(curAdr), "ArgsNum:"); - if (_value == "") { - Env->ErrAdr = curAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_value).c_str(), "%d", &_argsNum); - - while (_argsNum) { - _item = Env->Stack[_ESP_]; - if (_item.Flags & IF_INTVAL) - Env->AddToBody(String(_item.IntValue)); - else - Env->AddToBody(_item.Value); - _ESP_ += 4; - _argsNum--; - } - Env->AddToBody(");"); - return false; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -int __fastcall TDecompiler::GetCmpInfo(DWORD fromAdr) { - BYTE _b, _op; - int _curPos; - DWORD _curAdr = fromAdr; - DISINFO _disInfo; - - _curPos = Adr2Pos(_curAdr); - CmpAdr = 0; - - Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - if (_disInfo.Conditional && IsValidCodeAdr(_disInfo.Immediate)) { - _b = *(Code + _curPos); - if (_b == 0xF) - _b = *(Code + _curPos + 1); - _b = (_b & 0xF) + 'A'; - if (_b == 'A' || _b == 'B') - return CMP_FAILED; - CmpAdr = _disInfo.Immediate; - CmpOp = _b; - return CMP_BRANCH; - } - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_SET) { - CmpAdr = 0; - _b = *(Code + _curPos + 1); - CmpOp = (_b & 0xF) + 'A'; - return CMP_SET; - } - return CMP_FAILED; -} - -// --------------------------------------------------------------------------- -// "for" cycle types -// 1 - for I := C1 to C2 -// 2 - for I := 0 to N -// 3 - for I := 1 to N -// 4 - for I := C to N -// 5 - for I := N to C -// 6 - for I ;= N1 to N2 -// 7 - for I := C1 downto C2 -// 8 - for I := 0 downto N -// 9 - for I := C downto N -// 10 - for I := N downto C -// 11 - for I := N1 downto N2 -PLoopInfo __fastcall TDecompiler::GetLoopInfo(int fromAdr) { - bool noVar = true; - bool down = false; - bool bWhile = false; - BYTE _op; - int instrLen, pos, pos1, fromPos, num, intTo, idx, idxVal; - DWORD maxAdr, brkAdr, lastAdr, stopAdr, _dd, _dd1; - PInfoRec recN; - PLoopInfo res; - DISINFO _disInfo; - String from, to, cnt; - ITEM item; - IDXINFO varIdxInfo, cntIdxInfo; - - fromPos = Adr2Pos(fromAdr); - pos1 = GetNearestUpInstruction(fromPos); - Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'pmj') - bWhile = true; - - recN = GetInfoRec(fromAdr); - if (recN && recN->xrefs) { - maxAdr = 0; - for (int n = 0; n < recN->xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[n]; - if (recX->adr + recX->offset > maxAdr) - maxAdr = recX->adr + recX->offset; - } - // Instruction at maxAdr - instrLen = Disasm.Disassemble(Code + Adr2Pos(maxAdr), (__int64)maxAdr, &_disInfo, 0); - brkAdr = maxAdr + instrLen; - lastAdr = maxAdr; - if (bWhile) { - res = new TLoopInfo('W', fromAdr, brkAdr, lastAdr); // while - return res; - } - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'pmj') { - res = new TLoopInfo('T', fromAdr, brkAdr, lastAdr); // while true - res->whileInfo = new TWhileInfo(true); - return res; - } - // First instruction before maxAdr - pos1 = GetNearestUpInstruction(Adr2Pos(maxAdr), fromPos); - Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &_disInfo, 0); - _dd1 = *((DWORD*)_disInfo.Mnem); - // cmp reg/mem, imm - if (_dd1 == 'pmc' && _disInfo.OpType[1] == otIMM) { - noVar = false; - GetCycleIdx(&varIdxInfo, &_disInfo); - intTo = _disInfo.Immediate; - // Find mov reg/mem,... - pos = fromPos; - while (1) { - pos = GetNearestUpInstruction(pos); - instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - if (_disInfo.Branch || IsFlagSet(cfProcStart, pos)) { - res = new TLoopInfo('R', fromAdr, brkAdr, lastAdr); // repeat - return res; - } - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_MOV || _op == OP_XOR) { - if (varIdxInfo.IdxType == itREG && _disInfo.OpType[0] == otREG && IsSameRegister(_disInfo.OpRegIdx[0], varIdxInfo.IdxValue)) { - GetRegItem(varIdxInfo.IdxValue, &item); - if (item.Flags & IF_INTVAL) { - from = String(item.IntValue); - item.Flags &= ~IF_INTVAL; - } - else - from = item.Value; - item.Value = GetDecompilerRegisterName(varIdxInfo.IdxValue); - SetRegItem(varIdxInfo.IdxValue, &item); - break; - } - if (varIdxInfo.IdxType == itLVAR && _disInfo.OpType[0] == otMEM) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - if (item.IntValue + _disInfo.Offset == varIdxInfo.IdxValue) { - if (Env->Stack[varIdxInfo.IdxValue].Flags & IF_INTVAL) - from = String(Env->Stack[varIdxInfo.IdxValue].IntValue); - else - from = Env->Stack[varIdxInfo.IdxValue].Value; - Env->Stack[varIdxInfo.IdxValue].Value = Env->GetLvarName(varIdxInfo.IdxValue, "Integer"); - break; - } - } - if (_disInfo.BaseReg == 20) // [esp+N] - { - if (_ESP_ + _disInfo.Offset == varIdxInfo.IdxValue) { - if (Env->Stack[varIdxInfo.IdxValue].Flags & IF_INTVAL) - from = String(Env->Stack[varIdxInfo.IdxValue].IntValue); - else - from = Env->Stack[varIdxInfo.IdxValue].Value; - Env->Stack[varIdxInfo.IdxValue].Value = Env->GetLvarName(varIdxInfo.IdxValue, "Integer"); - break; - } - } - } - } - } - // Find array elements - pos += instrLen; - while (1) { - if (pos == fromPos) - break; - - instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // lea reg, mem - if (_op == OP_LEA && _disInfo.OpType[1] == otMEM) { - idx = _disInfo.OpRegIdx[0]; - GetRegItem(idx, &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(idx, &item); - pos += instrLen; - continue; - } - // mov reg, esp - if (_op == OP_MOV && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[1] == 20) { - idx = _disInfo.OpRegIdx[0]; - GetRegItem(idx, &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(idx, &item); - pos += instrLen; - continue; - } - // mov - if (_op == OP_MOV) { - if (_disInfo.OpType[1] == otIMM && IsValidImageAdr(_disInfo.Immediate)) { - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(_disInfo.OpRegIdx[0], &item); - } - if (_disInfo.OpType[0] == otMEM) { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; - } - } - } - if (_disInfo.OpType[1] == otREG) { - GetRegItem(_disInfo.OpRegIdx[1], &item); - if (item.Flags & IF_ARRAY_PTR) { - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(_disInfo.OpRegIdx[0], &item); - } - if (_disInfo.OpType[0] == otMEM) { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; - } - } - } - } - if (_disInfo.OpType[1] == otMEM) { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - if (Env->Stack[idxVal].Flags & IF_ARRAY_PTR) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(_disInfo.OpRegIdx[0], &item); - } - } - } - } - pos += instrLen; - } - // 4 - pos = Adr2Pos(maxAdr); - stopAdr = brkAdr; - pos = GetNearestUpInstruction(pos); - while (1) { - pos = GetNearestUpInstruction(pos); - Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'cni' || _dd == 'ced' || _dd == 'dda' || _dd == 'bus') { - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - if (item.Flags & IF_ARRAY_PTR) { - stopAdr = Pos2Adr(pos); - continue; - } - if (varIdxInfo.IdxType == itREG && IsSameRegister(_disInfo.OpRegIdx[0], varIdxInfo.IdxValue)) { - if (_dd == 'ced') - down = true; - stopAdr = Pos2Adr(pos); - } - break; - } - if (_disInfo.OpType[0] == otMEM) { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - if (Env->Stack[idxVal].Flags & IF_ARRAY_PTR) { - stopAdr = Pos2Adr(pos); - continue; - } - if (varIdxInfo.IdxType == itLVAR && varIdxInfo.IdxValue == idxVal) { - if (_dd == 'ced') - down = true; - stopAdr = Pos2Adr(pos); - } - } - break; - } - } - break; - } - res = new TLoopInfo('F', fromAdr, brkAdr, lastAdr); // for - if (!down) - to = String(intTo - 1); - else - to = String(intTo + 1); - res->forInfo = new TForInfo(noVar, down, stopAdr, from, to, varIdxInfo.IdxType, varIdxInfo.IdxValue, -1, -1); - return res; - } - if (_dd1 == 'cni' || _dd1 == 'ced') { - from = "1"; - // 1 - GetCycleIdx(&cntIdxInfo, &_disInfo); - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - if (item.Flags & IF_INTVAL) - cnt = String(item.IntValue); - else if (item.Value1 != "") - cnt = item.Value1; - else - cnt = item.Value; - } - if (_disInfo.OpType[0] == otMEM) { - GetRegItem(_disInfo.BaseReg, &item); - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - item = Env->Stack[item.IntValue + _disInfo.Offset]; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - item = Env->Stack[_ESP_ + _disInfo.Offset]; - } - if (item.Flags & IF_INTVAL) - cnt = String(item.IntValue); - else - cnt = item.Value; - } - } - // 2 - pos = fromPos; - while (1) { - pos = GetNearestUpInstruction(pos); - instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - if (SameText(cntIdxInfo.IdxStr, String(_disInfo.Op1))) - break; - } - // 3 - pos += instrLen; - while (1) { - if (pos == fromPos) - break; - - instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // lea reg1, mem - if (_op == OP_LEA && _disInfo.OpType[1] == otMEM) { - idx = _disInfo.OpRegIdx[0]; - GetRegItem(idx, &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(idx, &item); - pos += instrLen; - continue; - } - // mov reg, esp - if (_op == OP_MOV && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[1] == 20) { - idx = _disInfo.OpRegIdx[0]; - GetRegItem(idx, &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(idx, &item); - pos += instrLen; - continue; - } - if (_op == OP_MOV) { - if (_disInfo.OpType[1] == otIMM) { - if (!IsValidImageAdr(_disInfo.Immediate)) { - GetCycleIdx(&varIdxInfo, &_disInfo); - noVar = false; - } - else { - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(_disInfo.OpRegIdx[0], &item); - } - else // otMEM - { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; - } - } - } - } - if (_disInfo.OpType[1] == otREG) { - GetRegItem(_disInfo.OpRegIdx[1], &item); - int _size; - int _kind = GetTypeKind(item.Type, &_size); - if ((item.Flags & IF_ARRAY_PTR) || _kind == ikArray || _kind == ikDynArray) { - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(_disInfo.OpRegIdx[0], &item); - } - else // otMEM - { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - Env->Stack[idxVal].Flags |= IF_ARRAY_PTR; - } - } - } - else { - GetCycleIdx(&varIdxInfo, &_disInfo); - noVar = false; - } - } - if (_disInfo.OpType[1] == otMEM) { - // ??????!!!!!! - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - item = Env->Stack[idxVal]; - if (item.Flags & IF_VAR) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - item.Flags |= IF_ARRAY_PTR; - SetRegItem(_disInfo.OpRegIdx[0], &item); - pos += instrLen; - continue; - } - if (!(item.Flags & IF_ARRAY_PTR)) { - GetCycleIdx(&varIdxInfo, &_disInfo); - noVar = false; - } - } - } - } - pos += instrLen; - } - // 4 - pos = GetNearestUpInstruction(Adr2Pos(maxAdr)); - stopAdr = Pos2Adr(pos); - while (1) { - pos = GetNearestUpInstruction(pos); - Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'cni' || _dd == 'ced' || _dd == 'dda' || _dd == 'bus') { - if (_disInfo.OpType[0] == otREG) { - GetRegItem(_disInfo.OpRegIdx[0], &item); - if (item.Flags & IF_ARRAY_PTR) { - stopAdr = Pos2Adr(pos); - continue; - } - if (noVar) { - GetCycleIdx(&varIdxInfo, &_disInfo); - if (item.Flags & IF_INTVAL) { - from = String(item.IntValue); - item.Flags &= ~IF_INTVAL; - } - else - from = item.Value; - stopAdr = Pos2Adr(pos); - } - else { - if (varIdxInfo.IdxType == itREG && IsSameRegister(_disInfo.OpRegIdx[0], varIdxInfo.IdxValue)) { - if (_dd == 'ced') - down = true; - stopAdr = Pos2Adr(pos); - } - } - break; - } - if (_disInfo.OpType[0] == otMEM) { - if (_disInfo.BaseReg == 21 || _disInfo.BaseReg == 20) { - if (_disInfo.BaseReg == 21) // [ebp-N] - { - GetRegItem(_disInfo.BaseReg, &item); - idxVal = item.IntValue + _disInfo.Offset; - } - if (_disInfo.BaseReg == 20) // [esp-N] - { - idxVal = _ESP_ + _disInfo.Offset; - } - item = Env->Stack[idxVal]; - if (item.Flags & IF_ARRAY_PTR) { - stopAdr = Pos2Adr(pos); - continue; - } - if (!noVar && varIdxInfo.IdxType == itLVAR && varIdxInfo.IdxValue == idxVal) { - if (_dd == 'ced') - down = true; - stopAdr = Pos2Adr(pos); - } - break; - } - } - } - break; - } - // from, to - if (noVar) { - // from = "1"; - if (cntIdxInfo.IdxType == itREG) { - if (SameText(from, "1")) - to = cnt; - else - to = cnt + " + " + from + " - 1"; - GetRegItem(cntIdxInfo.IdxValue, &item); - if (item.Flags & IF_INTVAL) { - // to = String(item.IntValue); - item.Flags &= ~IF_INTVAL; - } - // else - // to = item.Value; - item.Value = GetDecompilerRegisterName(cntIdxInfo.IdxValue); - SetRegItem(cntIdxInfo.IdxValue, &item); - } - else if (cntIdxInfo.IdxType == itLVAR) { - item = Env->Stack[cntIdxInfo.IdxValue]; - if (item.Flags & IF_INTVAL) { - // to = String(item.IntValue); - item.Flags &= ~IF_INTVAL; - } - // else - // to = item.Value; - item.Value = Env->GetLvarName(cntIdxInfo.IdxValue, "Integer"); - Env->Stack[cntIdxInfo.IdxValue] = item; - } - } - else { - if (varIdxInfo.IdxType == itREG) { - GetRegItem(varIdxInfo.IdxValue, &item); - if (item.Flags & IF_INTVAL) { - if (from == "") - from = String(item.IntValue); - item.Flags &= ~IF_INTVAL; - } - else if (from == "") - from = item.Value; - item.Value = GetDecompilerRegisterName(varIdxInfo.IdxValue); - item.Flags |= IF_CYCLE_VAR; - SetRegItem(varIdxInfo.IdxValue, &item); - } - else if (varIdxInfo.IdxType == itLVAR) { - item = Env->Stack[varIdxInfo.IdxValue]; - from = item.Value1; - item.Value = Env->GetLvarName(varIdxInfo.IdxValue, "Integer"); - item.Flags |= IF_CYCLE_VAR; - Env->Stack[varIdxInfo.IdxValue] = item; - } - if (cntIdxInfo.IdxType == itREG) { - GetRegItem(cntIdxInfo.IdxValue, &item); - if (item.Flags & IF_INTVAL) { - if (cnt == "") - cnt = String(item.IntValue); - item.Flags &= ~IF_INTVAL; - } - else if (cnt == "") - cnt = item.Value; - item.Value = GetDecompilerRegisterName(cntIdxInfo.IdxValue); - SetRegItem(cntIdxInfo.IdxValue, &item); - } - else if (cntIdxInfo.IdxType == itLVAR) { - cnt = Env->Stack[cntIdxInfo.IdxValue].Value; - Env->Stack[cntIdxInfo.IdxValue].Value = Env->GetLvarName(cntIdxInfo.IdxValue, "Integer"); - } - if (SameText(from, "1")) - to = cnt; - else if (SameText(from, "0")) - to = cnt + " - 1"; - else { - to = cnt + " + " + from + " - 1"; - } - } - res = new TLoopInfo('F', fromAdr, brkAdr, lastAdr); // for - res->forInfo = new TForInfo(noVar, false, stopAdr, from, to, varIdxInfo.IdxType, varIdxInfo.IdxValue, cntIdxInfo.IdxType, cntIdxInfo.IdxValue); - return res; - } - } - res = new TLoopInfo('R', fromAdr, brkAdr, lastAdr); // repeat - return res; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulatePush(DWORD curAdr, bool bShowComment) { - bool _vmt; - int _offset, _idx; - BYTE *_pdi, _b; - DWORD _vmtAdr; // , _imm; - ITEM _item, _item1; - PInfoRec _recN; - String _name, _type, _typeName, _value, _regname; - - // push imm - if (DisInfo.OpType[0] == otIMM) { - if (IsValidImageAdr(DisInfo.Immediate)) { - _recN = GetInfoRec(DisInfo.Immediate); - if (_recN && (_recN->kind == ikLString || _recN->kind == ikWString || _recN->kind == ikUString)) { - InitItem(&_item); - _item.Value = _recN->GetName(); - _item.Type = "String"; - Push(&_item); - return; - } - } - - InitItem(&_item); - _item.Flags = IF_INTVAL; - /* - _pdi = (BYTE*)&DisInfo.Immediate; _b = *_pdi; - if (DisInfo.ImmSize == 1)//byte - { - if (_b & 0x80) - _imm = 0xFFFFFF00 | _b; - else - _imm = _b; - } - else if (DisInfo.ImmSize == 2)//word - { - if (_b & 0x80) - _imm = 0xFFFF0000 | _b; - else - _imm = _b; - } - else - { - _imm = DisInfo.Immediate; - } - */ - _item.IntValue = DisInfo.Immediate; - Push(&_item); - return; - } - // push reg - if (DisInfo.OpType[0] == otREG) { - _idx = DisInfo.OpRegIdx[0]; - // push esp - if (_idx == 20) { - InitItem(&_item); - _item.Flags = IF_STACK_PTR; - _item.IntValue = _ESP_; - Push(&_item); - return; - } - GetRegItem(_idx, &_item); - - _regname = GetDecompilerRegisterName(_idx); - if (_item.Value != "" && !SameText(_regname, _item.Value)) - _value = _item.Value + "{" + _regname + "}"; - _item.Value = _value; - - // push eax - clear flag IF_CALL_RESULT - if (_item.Flags & IF_CALL_RESULT) { - _item.Flags &= ~IF_CALL_RESULT; - SetRegItem(_idx, &_item); - } - // if (_item.Flags & IF_ARG) - // { - // _item.Flags &= ~IF_ARG; - // _item.Name = ""; - // } - - Push(&_item); - if (bShowComment) - Env->AddToBody("//push " + _regname); - return; - } - // push mem - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_item, OP_PUSH); - Push(&_item); - return; - _offset = DisInfo.Offset; - // push [BaseReg + IndxReg*Scale + Offset] - if (DisInfo.BaseReg != -1) { - if (DisInfo.BaseReg == 20) { - _item = Env->Stack[_ESP_ + _offset]; - Push(&_item); - return; - } - - GetRegItem(DisInfo.BaseReg, &_item1); - // cop reg, [BaseReg + Offset] - if (DisInfo.IndxReg == -1) { - // push [ebp-N] - if (_item1.Flags & IF_STACK_PTR) { - _name = Env->GetLvarName(_item1.IntValue + _offset, ""); - _item = Env->Stack[_item1.IntValue + _offset]; - _item.Value = _name; - Push(&_item); - return; - } - // push [reg] - if (!_offset) { - // var - if (_item1.Flags & IF_VAR) { - InitItem(&_item); - _item.Value = _item1.Value; - _item.Type = _item1.Type; - Push(&_item); - return; - } - if (IsValidImageAdr(_item1.IntValue)) { - _recN = GetInfoRec(_item1.IntValue); - if (_recN) { - InitItem(&_item); - _item.Value = _recN->GetName(); - _item.Type = _recN->type; - Push(&_item); - return; - } - } - } - _typeName = TrimTypeName(GetRegType(DisInfo.BaseReg)); - if (_typeName != "") { - if (_typeName[1] == '^') // Pointer to gvar (from other unit) - { - InitItem(&_item); - _item.Value = _item1.Value; - _item.Type = GetTypeDeref(_typeName); - Push(&_item); - return; - } - // push [reg+N] - if (FMain_11011981->GetField(_typeName, _offset, _name, _type)) { - InitItem(&_item); - - if (SameText(_item1.Value, "Self")) - _item.Value = _name; - else - _item.Value = _item1.Value + "." + _name; - - _item.Type = _type; - Push(&_item); - return; - } - } - } - } - // [Offset] - if (IsValidImageAdr(_offset)) { - _recN = GetInfoRec(_offset); - if (_recN) { - InitItem(&_item); - _item.Value = _recN->GetName(); - _item.Type = _recN->type; - Push(&_item); - return; - } - InitItem(&_item); - Push(&_item); - return; - } - else { - Env->ErrAdr = curAdr; - throw Exception("Address is outside program image"); - } - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulatePop(DWORD curAdr) { - String _regname; - PITEM _item; - - // pop reg - if (DisInfo.OpType[0] == otREG) { - _item = Pop(); - if (!IsFlagSet(cfFrame, Adr2Pos(curAdr))) { - _regname = GetDecompilerRegisterName(DisInfo.OpRegIdx[0]); - // _line = _regname + " := "; - // if (_item->Flags & IF_ARG) - // _line += _item->Name; - // else - // _line += _item->Value; - Env->AddToBody("//pop " + _regname); - } - _item->Precedence = PRECEDENCE_NONE; - _item->Value = _regname; - SetRegItem(DisInfo.OpRegIdx[0], _item); - return; - } - // pop mem - if (DisInfo.OpType[0] == otMEM) { - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -// Simulate instruction with 1 operand -void __fastcall TDecompiler::SimulateInstr1(DWORD curAdr, BYTE Op) { - int _regIdx, _offset; - ITEM _item, _item1, _item2, _itemBase, _itemSrc; - String _name, _value, _line, _comment; - - // op reg - if (DisInfo.OpType[0] == otREG) { - _regIdx = DisInfo.OpRegIdx[0]; - if (Op == OP_INC) { - GetRegItem(_regIdx, &_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = _item.Value + " + 1"; - SetRegItem(_regIdx, &_item); - _line = GetDecompilerRegisterName(_regIdx) + " := " + GetDecompilerRegisterName(_regIdx) + " + 1;"; - if (_item.Value != "") - _line += "//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_DEC) { - GetRegItem(_regIdx, &_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = _item.Value + " - 1"; - SetRegItem(_regIdx, &_item); - _line = GetDecompilerRegisterName(_regIdx) + " := " + GetDecompilerRegisterName(_regIdx) + " - 1;"; - if (_item.Value != "") - _line += "//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_IMUL) { - GetRegItem(_regIdx, &_item1); - GetRegItem(16, &_item2); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = _item1.Value + " * " + _item2.Value; - _item.Type = "Int64"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := " + GetDecompilerRegisterName(_regIdx) + " * " + "EAX;"; - if (_item.Value != "") - _line += "//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_NEG) { - GetRegItem(_regIdx, &_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "-" + _item.Value; - SetRegItem(_regIdx, &_item); - _line = GetDecompilerRegisterName(_regIdx) + " := -" + GetDecompilerRegisterName(_regIdx) + ";"; - if (_item.Value != "") - _line += "//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_NOT) { - GetRegItem(_regIdx, &_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "not " + _item.Value; - SetRegItem(_regIdx, &_item); - _line = GetDecompilerRegisterName(_regIdx) + " := not " + GetDecompilerRegisterName(_regIdx) + ";"; - if (_item.Value != "") - _line += "//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_SET) { - InitItem(&_item); - _item.Value = CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R; - _item.Type = "Boolean"; - SetRegItem(_regIdx, &_item); - _line = GetDecompilerRegisterName(_regIdx) + " := " + "(" + _item.Value + ");"; - Env->AddToBody(_line); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - // op mem - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, Op); - if (_itemSrc.Name != "") - _value = _itemSrc.Name; - else - _value = _itemSrc.Value; - if (Op == OP_IMUL) { - GetRegItem(16, &_item1); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = _value + " * " + _item1.Value; ; - _item.Type = "Int64"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := " + _item.Value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SET) { - _line = _value + " := (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ");"; - Env->AddToBody(_line); - return; - } - if (Op == OP_NEG) { - _line = _value + " := -" + _value + ";"; - Env->AddToBody(_line); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - - _offset = DisInfo.Offset; - if (DisInfo.BaseReg != -1) { - if (DisInfo.IndxReg == -1) { - GetRegItem(DisInfo.BaseReg, &_itemBase); - // op [esp+N] - if (DisInfo.BaseReg == 20) { - if (Op == OP_IMUL) { - _item1 = Env->Stack[_ESP_ + _offset]; - GetRegItem(16, &_item2); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = _item1.Value + " * " + _item2.Value; - _item.Type = "Integer"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := EAX * " + Env->GetLvarName(_ESP_ + _offset, "Integer") + ";//" + _item1.Value; - Env->AddToBody(_line); - return; - } - } - // op [ebp-N] - if (DisInfo.BaseReg == 21 && (_itemBase.Flags & IF_STACK_PTR)) { - if (Op == OP_IMUL) { - _item1 = Env->Stack[_itemBase.IntValue + _offset]; - GetRegItem(16, &_item2); - if (_item1.Value != "") - _name = _item1.Value; - else - _name = Env->GetLvarName(_itemBase.IntValue + _offset, "Integer"); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = _name + " * " + _item2.Value; - _item.Type = "Integer"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := EAX * " + Env->GetLvarName(_ESP_ + _offset, "Integer") + ";//" + _item.Value; - Env->AddToBody(_line); - return; - } - } - if (_itemBase.Type[1] == '^') // Pointer to gvar (from other unit) - { - if (Op == OP_IMUL) { - GetRegItem(16, &_item2); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(&_item2, PRECEDENCE_MULT) + " * " + GetString(&_itemBase, PRECEDENCE_MULT + 1); - _item.Type = "Integer"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := EAX * " + _itemBase.Value + ";//" + _item.Value; - Env->AddToBody(_line); - return; - } - } - } - } - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateInstr2RegImm(DWORD curAdr, BYTE Op) { - bool _vmt; - BYTE _kind, _kind1, _kind2; - char *_tmpBuf; - int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size; - int _idx, _classSize, _dotpos, _len, _ap; - DWORD _vmtAdr, _adr; - ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; - ITEM _item, _item1, _item2; - PInfoRec _recN, _recN1; - PLOCALINFO _locInfo; - String _name, _type, _value, _typeName, _line, _comment, _imm, _iname, _fname, _text; - WideString _wStr; - - _reg1Idx = DisInfo.OpRegIdx[0]; - _imm = GetImmString(DisInfo.Immediate); - if (Op == OP_MOV) { - InitItem(&_item); - _item.Flags = IF_INTVAL; - _item.IntValue = DisInfo.Immediate; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _imm + ";"; - Env->AddToBody(_line); - return; - - if (IsValidImageAdr(DisInfo.Immediate)) { - _ap = Adr2Pos(DisInfo.Immediate); - if (_ap >= 0) { - _recN = GetInfoRec(DisInfo.Immediate); - if (_recN) { - _kind1 = _recN->kind; - if (_kind1 == ikPointer) { - _item.Flags = IF_INTVAL; - _item.IntValue = DisInfo.Immediate; - SetRegItem(_reg1Idx, &_item); - return; - } - if (_kind1 == ikUnknown || _kind1 == ikData) - _kind1 = GetTypeKind(_recN->type, &_size); - - switch (_kind1) { - case ikSet: - _item.Flags = IF_INTVAL; - _item.IntValue = DisInfo.Immediate; - _item.Value = GetDecompilerRegisterName(_reg1Idx); - _item.Type = _recN->type; - break; - case ikString: - _item.Value = _recN->GetName(); - _item.Type = "ShortString"; - break; - case ikLString: - _item.Value = _recN->GetName(); - _item.Type = "String"; - break; - case ikWString: - _item.Value = _recN->GetName(); - _item.Type = "WideString"; - break; - case ikUString: - _item.Value = _recN->GetName(); - _item.Type = "UnicodeString"; - break; - case ikCString: - _item.Value = _recN->GetName(); - _item.Type = "PChar"; - break; - case ikWCString: - _len = wcslen((wchar_t*)(Code + _ap)); - _wStr = WideString((wchar_t*)(Code + _ap)); - _size = WideCharToMultiByte(CP_ACP, 0, _wStr.c_bstr(), _len, 0, 0, 0, 0); - if (_size) { - _tmpBuf = new char[_size + 1]; - WideCharToMultiByte(CP_ACP, 0, _wStr.c_bstr(), _len, (LPSTR)_tmpBuf, _size, 0, 0); - _recN->SetName(TransformString(_tmpBuf, _size)); - delete[]_tmpBuf; - } - _item.Value = _recN->GetName(); - _item.Type = "PWideChar"; - break; - case ikResString: - Env->LastResString = _recN->rsInfo->value; - _item.Value = _recN->GetName(); - _item.Type = "PResStringRec"; - break; - case ikArray: - _item.Value = _recN->GetName(); - _item.Type = _recN->type; - break; - case ikDynArray: - _item.Value = _recN->GetName(); - _item.Type = _recN->type; - break; - default: - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - SetRegItem(_reg1Idx, &_item); - return; - } - } - else { - _idx = BSSInfos->IndexOf(Val2Str8(DisInfo.Immediate)); - if (_idx != -1) { - _recN = (PInfoRec)BSSInfos->Objects[_idx]; - _item.Value = _recN->GetName(); - _item.Type = _recN->type; - } - else { - _item.Value = MakeGvarName(DisInfo.Immediate); - AddToBSSInfos(DisInfo.Immediate, _item.Value, ""); - } - SetRegItem(_reg1Idx, &_item); - return; - } - } - _item.Flags = IF_INTVAL; - _item.IntValue = DisInfo.Immediate; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _imm + ";"; - Env->AddToBody(_line); - return; - } - // cmp reg, imm - if (Op == OP_CMP) { - GetRegItem(_reg1Idx, &_item); - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - if (_item.Value != "" && !SameText(_item.Value, CmpInfo.L)) - CmpInfo.L += "{" + _item.Value + "}"; - CmpInfo.O = CmpOp; - CmpInfo.R = GetImmString(_item.Type, DisInfo.Immediate); - return; - } - // test reg, imm - if (Op == OP_TEST) { - GetRegItem(_reg1Idx, &_item); - _kind = GetTypeKind(_item.Type, &_size); - if (_kind == ikSet) { - CmpInfo.L = GetSetString(_item.Type, (BYTE*)&DisInfo.Immediate); - CmpInfo.O = CmpOp + 12; // look GetDirectCondition (in) - CmpInfo.R = GetDecompilerRegisterName(_reg1Idx); - return; - } - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx) + " And " + _imm; - CmpInfo.O = CmpOp; - CmpInfo.R = "0"; - return; - } - // add reg, imm (points to class field) - if (Op == OP_ADD) { - // add esp, imm - if (_reg1Idx == 20) { - _ESP_ += (int)DisInfo.Immediate; - return; - } - // add reg, imm - GetRegItem(_reg1Idx, &_item1); - // If stack ptr - if (_item1.Flags & IF_STACK_PTR) { - _item1.IntValue += (int)DisInfo.Immediate; - SetRegItem(_reg1Idx, &_item1); - return; - } - if (_item1.Type != "") { - if (_item1.Type[1] == '^') { - _typeName = GetTypeDeref(_item1.Type); - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _value = _item1.Value; - InitItem(&_item); - - _item.Flags = IF_RECORD_FOFS; - _item.Value = _value; - _item.Type = _typeName; - _item.Offset = (int)DisInfo.Immediate; - SetRegItem(_reg1Idx, &_item); - return; - /* - _text = GetRecordFields(DisInfo.Immediate, _typeName); - if (_text.Pos(":")) - { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else - { - _value += ".f" + Val2Str0(DisInfo.Immediate); - _typeName = _text; - } - _item.Value = _value; - _item.Type = _typeName; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := ^" + _item.Value; - Env->AddToBody(_line); - return; - */ - } - } - if (FMain_11011981->GetField(_item1.Type, DisInfo.Immediate, _name, _type)) { - InitItem(&_item); - - if (SameText(_item1.Value, "Self")) - _item.Value = _name; - else - _item.Value = _item1.Value + "." + _name; - - _item.Type = _type; - - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item.Value; - Env->AddToBody(_line); - return; - } - } - if (_item1.Value != "") - _value = GetString(&_item1, PRECEDENCE_ADD) + " + " + _imm; - else - _value = GetDecompilerRegisterName(_reg1Idx) + " + " + _imm; - // -1 and +1 for cycles - if (DisInfo.Immediate == 1 && _item1.Value != "") { - _len = _item1.Value.Length(); - if (_len > 4) { - if (SameText(_item1.Value.SubString(_len - 3, 4), " - 1")) { - _item1.Value = _item1.Value.SubString(1, _len - 4); - _item1.Precedence = PRECEDENCE_NONE; - SetRegItem(_reg1Idx, &_item1); - return; - } - } - } - - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - CmpInfo.O = CmpOp; - CmpInfo.R = 0; - - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetDecompilerRegisterName(_reg1Idx); - SetRegItem(_reg1Idx, &_item); - - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " + " + _imm; - _comment = _item.Value; - Env->AddToBody(_line + ";//" + _comment); - return; - } - // sub reg, imm - if (Op == OP_SUB) { - // sub esp, imm - if (_reg1Idx == 20) { - _ESP_ -= (int)DisInfo.Immediate; - return; - } - GetRegItem(_reg1Idx, &_item1); - // If reg point to VMT - return (may be operation with Interface) - if (GetTypeKind(_item1.Type, &_size) == ikVMT) - return; - - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - CmpInfo.O = CmpOp; - CmpInfo.R = 0; - - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetDecompilerRegisterName(_reg1Idx); - SetRegItem(_reg1Idx, &_item); - - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " - " + _imm; - _comment = _item.Value; - Env->AddToBody(_line + ";//" + _comment); - return; - } - // and reg, imm - if (Op == OP_AND) { - GetRegItem(_reg1Idx, &_item1); - if (DisInfo.Immediate == 0xFF && SameText(_item1.Type, "Byte")) - return; - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " And " + _imm; - SetRegItem(_reg1Idx, &_item); - - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " And " + _imm; - _comment = _item.Value; - Env->AddToBody(_line + ";//" + _comment); - return; - } - // or reg, imm - if (Op == OP_OR) { - GetRegItem(_reg1Idx, &_item1); - InitItem(&_item); - if (DisInfo.Immediate == -1) { - _item.Flags = IF_INTVAL; - _item.IntValue = -1; - _item.Type = "Cardinal"; - } - else { - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(&_item1, PRECEDENCE_ADD) + " Or " + _imm; - _item.Type = "Cardinal"; - } - SetRegItem(_reg1Idx, &_item); - - _line = GetDecompilerRegisterName(_reg1Idx) + " := "; - if (DisInfo.Immediate != -1) - _line += GetDecompilerRegisterName(_reg1Idx) + " Or "; - _line += _imm; - Env->AddToBody(_line + ";"); - return; - } - // sal(shl) reg, imm - if (Op == OP_SAL || Op == OP_SHL) { - _pow2 = 1; - for (int n = 0; n < DisInfo.Immediate; n++) - _pow2 *= 2; - GetRegItem(_reg1Idx, &_item1); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (Op == OP_SHL) { - _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Shl " + String(DisInfo.Immediate); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Shl " + String(DisInfo.Immediate); - _comment = GetString(&_item1, PRECEDENCE_MULT) + " * " + String(_pow2); - } - else { - _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " * " + String(_pow2); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " * " + String(_pow2); - _comment = ""; - } - SetRegItem(_reg1Idx, &_item); - if (_comment != "") - _line += ";//" + _comment; - Env->AddToBody(_line); - return; - } - // sar(shr) reg, imm - if (Op == OP_SAR || Op == OP_SHR) { - _pow2 = 1; - for (int n = 0; n < DisInfo.Immediate; n++) - _pow2 *= 2; - GetRegItem(_reg1Idx, &_item1); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (Op == OP_SHR) { - _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Shr " + String(DisInfo.Immediate); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Shr " + String(DisInfo.Immediate); - _comment = GetString(&_item1, PRECEDENCE_MULT) + " Div " + String(_pow2); - } - else { - _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Div " + String(_pow2); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + String(_pow2); - _comment = ""; - } - SetRegItem(_reg1Idx, &_item); - if (_comment != "") - _line += ";//" + _comment; - Env->AddToBody(_line); - return; - } - // xor reg, imm - if (Op == OP_XOR) { - GetRegItem(_reg1Idx, &_item1); - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(&_item1, PRECEDENCE_ADD) + " Xor " + _imm; - SetRegItem(_reg1Idx, &_item); - - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Xor " + _imm; - _comment = _item.Value; - Env->AddToBody(_line + ";//" + _comment); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateInstr2RegReg(DWORD curAdr, BYTE Op) { - bool _vmt; - BYTE _kind; - int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _classSize, _dotpos; - DWORD _vmtAdr, _adr; - ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; - ITEM _item, _item1, _item2; - PInfoRec _recN, _recN1; - PLOCALINFO _locInfo; - PFIELDINFO _fInfo; - String _name, _value, _typeName, _line, _comment, _imm, _iname, _fname, _op; - - _reg1Idx = DisInfo.OpRegIdx[0]; - _reg2Idx = DisInfo.OpRegIdx[1]; - GetRegItem(_reg1Idx, &_item1); - GetRegItem(_reg2Idx, &_item2); - - if (Op == OP_MOV) { - if (IsSameRegister(_reg1Idx, _reg2Idx)) - return; - - // mov esp, reg - if (_reg1Idx == 20) { - SetRegItem(20, &_item2); - return; - } - // mov reg, esp - if (_reg2Idx == 20) { - InitItem(&_item); - _item.Flags = IF_STACK_PTR; - _item.IntValue = _ESP_; - SetRegItem(_reg1Idx, &_item); - // mov ebp, esp - if (Env->BpBased && _reg1Idx == 21 && !Env->LocBase) - Env->LocBase = _ESP_; - return; - } - // mov reg, reg - if (_item2.Flags & IF_ARG) { - if (_reg1Idx != _reg2Idx) { - _item2.Flags &= ~IF_ARG; - _item2.Name = ""; - SetRegItem(_reg1Idx, &_item2); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item2.Value + ";"; - Env->AddToBody(_line); - } - return; - } - // mov reg, eax (eax - call result) -> set eax to reg!!!! - if (_item2.Flags & IF_CALL_RESULT) { - _item2.Flags &= ~IF_CALL_RESULT; - _item2.Value1 = _item2.Value; - _item2.Value = GetDecompilerRegisterName(_reg1Idx); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _item2.Value1 + ";"; - SetRegItem(_reg1Idx, &_item2); - Env->AddToBody(_line); - return; - } - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg2Idx) + ";"; - if (_item2.Value != "") - _line += "//" + _item2.Value; - _item2.Flags = 0; - if (_item2.Value == "") - _item2.Value = GetDecompilerRegisterName(_reg2Idx); - SetRegItem(_reg1Idx, &_item2); - Env->AddToBody(_line); - return; - } - // cmp reg, reg - if (Op == OP_CMP) { - // _kind1 = GetTypeKind(_item1.Type, &_size); - // _kind2 = GetTypeKind(_item2.Type, &_size); - // !!! if kind1 <> kind2 ??? - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - if (_item1.Value != "" && !SameText(_item1.Value, CmpInfo.L)) - CmpInfo.L += "{" + _item1.Value + "}"; - CmpInfo.O = CmpOp; - CmpInfo.R = GetDecompilerRegisterName(_reg2Idx); - if (_item2.Value != "" && !SameText(_item2.Value, CmpInfo.R)) - CmpInfo.R += "{" + _item2.Value + "}"; - return; - } - if (Op == OP_TEST) { - if (_reg1Idx == _reg2Idx) { - // GetRegItem(_reg1Idx, &_item); - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - if (_item1.Value != "" && !SameText(_item1.Value, CmpInfo.L)) - CmpInfo.L += "{" + _item1.Value + "}"; - CmpInfo.O = CmpOp; - CmpInfo.R = GetImmString(_item1.Type, (Variant)0); - return; - } - else { - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx) + " And " + GetDecompilerRegisterName(_reg2Idx); - CmpInfo.O = CmpOp; - CmpInfo.R = "0"; - return; - } - } - if (Op == OP_ADD) - _op = " + "; - else if (Op == OP_SUB) - _op = " - "; - else if (Op == OP_OR) - _op = " Or "; - else if (Op == OP_XOR) - _op = " Xor "; - else if (Op == OP_MUL || Op == OP_IMUL) - _op = " * "; - else if (Op == OP_AND) - _op = " And "; - else if (Op == OP_SHR) - _op = " Shr "; - else if (Op == OP_SHL) - _op = " Shl "; - - if (Op == OP_ADD || Op == OP_SUB || Op == OP_OR || Op == OP_XOR) { - if (Op == OP_XOR && _reg1Idx == _reg2Idx) // xor reg,reg - { - Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := 0;"); - InitItem(&_item); - _item.Flags = IF_INTVAL; - _item.IntValue = 0; - SetRegItem(_reg1Idx, &_item); - return; - } - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + GetDecompilerRegisterName(_reg2Idx); - _comment = GetString(&_item1, PRECEDENCE_ADD) + _op + GetString(&_item2, PRECEDENCE_ADD + 1); - Env->AddToBody(_line + ";//" + _comment); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetDecompilerRegisterName(_reg1Idx); - SetRegItem(_reg1Idx, &_item); - - if (Op == OP_SUB) { - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - CmpInfo.O = CmpOp; - CmpInfo.R = GetDecompilerRegisterName(_reg2Idx); - } - return; - } - if (Op == OP_MUL || Op == OP_IMUL || Op == OP_AND || Op == OP_SHR || Op == OP_SHL) { - _line += GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + GetDecompilerRegisterName(_reg2Idx); - _comment = GetString(&_item1, PRECEDENCE_MULT) + _op + GetString(&_item2, PRECEDENCE_MULT + 1); - Env->AddToBody(_line + ";//" + _comment); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = _comment; - _item.Type = "Integer"; - SetRegItem(_reg1Idx, &_item); - return; - } - if (Op == OP_DIV || Op == OP_IDIV) { - _line = "EAX := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + GetDecompilerRegisterName(_reg2Idx); - _comment = GetString(&_item1, PRECEDENCE_MULT) + " Div " + GetString(&_item2, PRECEDENCE_MULT + 1); - Env->AddToBody(_line + ";//" + _comment); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = _comment; - _item.Type = "Integer"; - SetRegItem(16, &_item); - _item.Value = GetString(&_item1, PRECEDENCE_MULT) + " Mod " + GetString(&_item2, PRECEDENCE_MULT + 1); - SetRegItem(18, &_item); - return; - } - if (Op == OP_XCHG) { - SetRegItem(_reg1Idx, &_item2); - SetRegItem(_reg2Idx, &_item1); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateInstr2RegMem(DWORD curAdr, BYTE Op) { - bool _vmt; - BYTE _kind, _kind1, _kind2; - int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _idx1, _classSize, _ap; - DWORD _vmtAdr, _adr; - ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; - ITEM _item, _item1, _item2; - PInfoRec _recN, _recN1; - PLOCALINFO _locInfo; - PFIELDINFO _fInfo; - String _name, _value, _type, _line, _comment, _imm, _iname, _fname, _op; - - _reg1Idx = DisInfo.OpRegIdx[0]; - GetRegItem(_reg1Idx, &_itemDst); - - GetMemItem(curAdr, &_itemSrc, Op); - if ((_itemSrc.Flags & IF_VMT_ADR) || (_itemSrc.Flags & IF_EXTERN_VAR)) { - SetRegItem(_reg1Idx, &_itemSrc); - return; - } - _op = "?"; - if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || Op == OP_OR || Op == OP_AND || Op == OP_XOR) { - if (Op == OP_ADD) - _op = " + "; - else if (Op == OP_SUB) - _op = " - "; - else if (Op == OP_MUL || Op == OP_IMUL) - _op = " * "; - else if (Op == OP_OR) - _op = " Or "; - else if (Op == OP_AND) - _op = " And "; - else if (Op == OP_XOR) - _op = " Xor "; - } - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemSrc.IntValue]; - if (Op == OP_MOV) { - // Arg - if (_item.Flags & IF_ARG) { - // _item.Flags &= ~IF_VAR; - _item.Value = _item.Name; - SetRegItem(_reg1Idx, &_item); - Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := " + _item.Value + ";"); - return; - } - // Var - if (_item.Flags & IF_VAR) { - // _item.Flags &= ~IF_VAR; - SetRegItem(_reg1Idx, &_item); - return; - } - // Field - if (_item.Flags & IF_FIELD) { - _foffset = _item.Offset; - _fname = GetRecordFields(_foffset, Env->Stack[_itemSrc.IntValue - _foffset].Type); - _name = Env->Stack[_itemSrc.IntValue - _foffset].Value; - _type = ExtractType(_fname); - if (_name == "") - _name = Env->GetLvarName(_itemSrc.IntValue - _foffset, _type); - InitItem(&_itemDst); - if (_fname.Pos(":")) { - _itemDst.Value = _name + "." + ExtractName(_fname); - _itemDst.Type = _type; - } - else { - _itemDst.Value = _name + ".f" + Val2Str0(_foffset); - } - SetRegItem(_reg1Idx, &_itemDst); - Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := " + _itemDst.Value + ";"); - return; - } - - if (_item.Name != "") - _value = _item.Name; - else { - _value = Env->GetLvarName(_itemSrc.IntValue, ""); - if (_item.Value != "") - _value += "{" + _item.Value + "}"; - } - _item.Value = _value; - - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_LEA) { - SetRegItem(_reg1Idx, &_itemSrc); - return; - } - if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || Op == OP_OR || Op == OP_AND) { - // Field - if (_item.Flags & IF_FIELD) { - _foffset = _item.Offset; - _fname = GetRecordFields(_foffset, Env->Stack[_itemSrc.IntValue - _foffset].Type); - _name = Env->Stack[_itemSrc.IntValue - _foffset].Value; - - _itemDst.Flags = 0; - _itemDst.Precedence = PRECEDENCE_ADD; - if (_fname.Pos(":")) { - _itemDst.Value += _op + _name + "." + ExtractName(_fname); - _itemDst.Type = ExtractType(_fname); - } - else { - _itemDst.Value += _op + _name + ".f" + Val2Str0(_foffset); - } - SetRegItem(_reg1Idx, &_itemDst); - Env->AddToBody(GetDecompilerRegisterName(_reg1Idx) + " := " + _itemDst.Value + ";"); - return; - } - if (_itemSrc.Name != "") - _name = _itemSrc.Name; - else - _name = _itemSrc.Value; - - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _name + ";"; - _itemDst.Flags = 0; - if (Op == OP_ADD || Op == OP_SUB || Op == OP_OR) - _itemDst.Precedence = PRECEDENCE_ADD; - else if (Op == OP_MUL || Op == OP_IMUL || Op == OP_AND) - _itemDst.Precedence = PRECEDENCE_MULT; - _itemDst.Value = GetDecompilerRegisterName(_reg1Idx); - SetRegItem(_reg1Idx, &_itemDst); - Env->AddToBody(_line); - if (Op == OP_OR || Op == OP_AND) { - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - CmpInfo.O = CmpOp; - CmpInfo.R = "0"; - } - return; - } - if (Op == OP_CMP) { - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - if (_itemDst.Value != "" && !SameText(_itemDst.Value, CmpInfo.L)) - CmpInfo.L += "{" + _itemDst.Value + "}"; - CmpInfo.O = CmpOp; - if (_item.Flags & IF_ARG) - CmpInfo.R = _item.Name; - else - CmpInfo.R = _itemSrc.Value; - return; - } - if (Op == OP_XCHG) { - SetRegItem(_reg1Idx, &_item); - Env->Stack[_itemSrc.IntValue] = _itemDst; - return; - } - } - if (_itemSrc.Flags & IF_INTVAL) { - _offset = _itemSrc.IntValue; - if (Op == OP_MOV || Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL || Op == OP_DIV || Op == OP_IDIV) { - _name = ""; - _type = ""; - _ap = Adr2Pos(_offset); - _recN = GetInfoRec(_offset); - if (_recN) { - // VMT - if (_recN->kind == ikVMT || _recN->kind == ikDynArray) { - InitItem(&_item); - _item.Flags = IF_INTVAL; - _item.IntValue = _offset; - _item.Value = _recN->GetName(); - _item.Type = _recN->GetName(); - SetRegItem(_reg1Idx, &_item); - return; - } - MakeGvar(_recN, _offset, curAdr); - _name = _recN->GetName(); - _type = _recN->type; - - if (_ap >= 0) { - _adr = *(DWORD*)(Code + _ap); - // May be pointer to var - if (IsValidImageAdr(_adr)) { - _recN1 = GetInfoRec(_adr); - if (_recN1) { - MakeGvar(_recN1, _offset, curAdr); - InitItem(&_item); - _item.Value = _recN1->GetName(); - _item.Type = "^" + _recN1->type; - SetRegItem(_reg1Idx, &_item); - return; - } - } - } - } - // Just value - else { - InitItem(&_item); - _item.Flags = IF_INTVAL; - _item.IntValue = _offset; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _offset + ";"; - Env->AddToBody(_line); - return; - } - - if (Op == OP_MOV) { - InitItem(&_item); - _item.Value = _name; - _item.Type = _type; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _name + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_ADD || Op == OP_SUB || Op == OP_MUL || Op == OP_IMUL) { - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _name + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_DIV || Op == OP_IDIV) { - _line = GetDecompilerRegisterName(16) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + _name + ";"; - Env->AddToBody(_line); - _line = GetDecompilerRegisterName(18) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Mod " + _name + ";"; - Env->AddToBody(_line); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - if (Op == OP_CMP) { - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - if (_itemDst.Value != "" && !SameText(_itemDst.Value, CmpInfo.L)) - CmpInfo.L += "{" + _itemDst.Value + "}"; - CmpInfo.O = CmpOp; - _recN = GetInfoRec(_offset); - if (_recN) - CmpInfo.R = _recN->GetName(); - else - CmpInfo.R = MakeGvarName(_offset); - return; - } - } - if (Op == OP_MOV || Op == OP_LEA) { - // InitItem(&_item); - // _item.Flags = _itemSrc.Flags; - // _item.Type = _itemSrc.Type; - // _item.Value = _itemSrc.Value; - // if (Op == OP_LEA) - // _item.Type = "^" + _item.Type; - SetRegItem(_reg1Idx, &_itemSrc); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _itemSrc.Value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_CMP) { - CmpInfo.L = GetDecompilerRegisterName(_reg1Idx); - if (_itemDst.Value != "" && !SameText(_itemDst.Value, CmpInfo.L)) - CmpInfo.L += "{" + _itemDst.Value + "}"; - CmpInfo.O = CmpOp; - CmpInfo.R = _itemSrc.Value; - return; - } - if (Op == OP_ADD || Op == OP_SUB || Op == OP_XOR) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(&_itemDst, PRECEDENCE_ADD) + _op + GetString(&_itemSrc, PRECEDENCE_ADD + 1); - _item.Type = _itemSrc.Type; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _itemSrc.Value + ";//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_MUL || Op == OP_IMUL || Op == OP_AND) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(&_itemDst, PRECEDENCE_MULT) + _op + GetString(&_itemSrc, PRECEDENCE_MULT + 1); - _item.Type = _itemSrc.Type; - SetRegItem(_reg1Idx, &_item); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + GetDecompilerRegisterName(_reg1Idx) + _op + _itemSrc.Value + ";//" + _item.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_DIV || Op == OP_IDIV) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(&_itemDst, PRECEDENCE_MULT) + " Div " + GetString(&_itemSrc, PRECEDENCE_MULT + 1); - _item.Type = _itemSrc.Type; - SetRegItem(16, &_item); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(&_itemDst, PRECEDENCE_MULT) + " Mod " + GetString(&_itemSrc, PRECEDENCE_MULT + 1); - _itemDst.Type = _itemSrc.Type; - SetRegItem(18, &_item); - - _line = GetDecompilerRegisterName(16) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Div " + _itemSrc.Value + ";//" + _itemDst.Value + " Div " + _itemSrc.Value; - Env->AddToBody(_line); - _line = GetDecompilerRegisterName(18) + " := " + GetDecompilerRegisterName(_reg1Idx) + " Mod " + _itemSrc.Value + ";//" + _itemDst.Value + " Div " + _itemSrc.Value; - Env->AddToBody(_line); - return; - } - if (Op == OP_OR) { - // Dst - Set - if (GetTypeKind(_itemDst.Type, &_size) == ikSet) { - AssignItem(&_item1, &_itemDst); - AssignItem(&_item2, &_itemSrc); - } - // Src - Set - if (GetTypeKind(_itemSrc.Type, &_size) == ikSet) { - AssignItem(&_item1, &_itemSrc); - AssignItem(&_item2, &_itemDst); - } - _line = _item1.Value + " := " + _item1.Value + " + "; - if (_item2.Flags & IF_INTVAL) { - if (IsValidImageAdr(_item2.IntValue)) - _line += GetSetString(_item1.Type, Code + Adr2Pos(_item2.IntValue)); - else - _line += GetSetString(_item1.Type, (BYTE*)&_item2.IntValue); - } - else - _line += _item2.Value; - _line += ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_XCHG) { - SetRegItem(_reg1Idx, &_itemSrc); - Env->Stack[_itemSrc.IntValue] = _itemDst; - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateInstr2MemImm(DWORD curAdr, BYTE Op) { - bool _vmt; - BYTE _kind, _kind1, _kind2; - int _reg1Idx, _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _idx1, _classSize, _ap; - DWORD _vmtAdr, _adr; - ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; - ITEM _item, _item1, _item2; - PInfoRec _recN, _recN1; - PLOCALINFO _locInfo; - PFIELDINFO _fInfo; - String _name, _value, _typeName, _line, _comment, _imm, _iname, _fname, _key, _type; - - _imm = GetImmString(DisInfo.Immediate); - GetMemItem(curAdr, &_itemDst, Op); - if (_itemDst.Flags & IF_STACK_PTR) { - if (_itemDst.Name != "") - _name = _itemDst.Name; - else - _name = _itemDst.Value; - _item = Env->Stack[_itemDst.IntValue]; - if (_item.Flags & IF_ARG) - _name = _item.Value; - if (Op == OP_MOV) { - Env->Stack[_itemDst.IntValue].Value1 = _imm; - _line = _name + " := " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_CMP) { - CmpInfo.L = _name; - CmpInfo.O = CmpOp; - CmpInfo.R = GetImmString(_item.Type, DisInfo.Immediate); - return; - } - if (Op == OP_ADD) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " + " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SUB) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " - " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_AND) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " And " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_OR) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " Or " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_XOR) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " Xor " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_TEST) { - _typeName = TrimTypeName(Env->Stack[_itemDst.IntValue].Type); - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikSet) { - CmpInfo.L = GetSetString(_typeName, (BYTE*)&DisInfo.Immediate); - CmpInfo.O = CmpOp + 12; - CmpInfo.R = _name; - return; - } - - CmpInfo.L = _name + " And " + _imm; - CmpInfo.O = CmpOp; - CmpInfo.R = "0"; - return; - } - if (Op == OP_SHR) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " Shr " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SHL) { - Env->Stack[_itemDst.IntValue].Value = _name; - _line = _name + " := " + _name + " Shl " + _imm + ";"; - Env->AddToBody(_line); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - if (_itemDst.Flags & IF_INTVAL) { - if (IsValidImageAdr(_itemDst.IntValue)) { - _name = MakeGvarName(_itemDst.IntValue); - _ap = Adr2Pos(_itemDst.IntValue); - if (_ap >= 0) { - _recN = GetInfoRec(_itemDst.IntValue); - if (_recN) { - if (_recN->HasName()) - _name = _recN->GetName(); - if (_recN->type != "") - _imm = GetImmString(_recN->type, DisInfo.Immediate); - } - } - else { - _idx = BSSInfos->IndexOf(Val2Str8(_itemDst.IntValue)); - if (_idx != -1) { - _recN = (PInfoRec)BSSInfos->Objects[_idx]; - _name = _recN->GetName(); - _type = _recN->type; - if (_type != "") - _imm = GetImmString(_type, DisInfo.Immediate); - } - else { - AddToBSSInfos(_itemDst.IntValue, _name, ""); - } - } - if (Op == OP_MOV) { - _line = _name + " := " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_CMP) { - CmpInfo.L = _name; - CmpInfo.O = CmpOp; - CmpInfo.R = _imm; - return; - } - if (Op == OP_ADD) { - _line = _name + " := " + _name + " + " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SUB) { - _line = _name + " := " + _name + " - " + _imm + ";"; - Env->AddToBody(_line); - return; - } - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - if (_itemDst.Name != "" && !IsDefaultName(_itemDst.Name)) - _name = _itemDst.Name; - else - _name = _itemDst.Value; - _typeName = TrimTypeName(_itemDst.Type); - if (_typeName == "") { - if (Op == OP_MOV) { - _line = _name + " := " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_CMP) { - CmpInfo.L = _name; - CmpInfo.O = CmpOp; - CmpInfo.R = _imm; - return; - } - if (Op == OP_ADD) { - _line = _name + " := " + _name + " + " + _imm + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SUB) { - _line = _name + " := " + _name + " - " + _imm + ";"; - Env->AddToBody(_line); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - _kind = GetTypeKind(_typeName, &_size); - if (Op == OP_MOV) { - if (_kind == ikMethod) { - if (IsValidImageAdr(DisInfo.Immediate)) { - _ap = Adr2Pos(DisInfo.Immediate); - if (_ap >= 0) { - _recN = GetInfoRec(DisInfo.Immediate); - if (_recN) { - if (_recN->HasName()) - _line = _name + " := " + _recN->GetName() + ";"; - else - _line = _name + " := " + GetDefaultProcName(DisInfo.Immediate); - } - if (IsFlagSet(cfProcStart, _ap)) { - _line = _name + " := " + GetDefaultProcName(DisInfo.Immediate); - } - } - else { - _idx = BSSInfos->IndexOfName(Val2Str8(DisInfo.Immediate)); - if (_idx != -1) { - _recN = (PInfoRec)BSSInfos->Objects[_idx]; - _line = _name + " := " + _recN->GetName() + ";"; - } - else { - AddToBSSInfos(DisInfo.Immediate, MakeGvarName(DisInfo.Immediate), ""); - _line = _name + " := " + MakeGvarName(DisInfo.Immediate); - } - } - Env->AddToBody(_line); - return; - } - } - _line = _name + " := " + GetImmString(_typeName, DisInfo.Immediate) + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_CMP) { - CmpInfo.L = _name; - CmpInfo.O = CmpOp; - CmpInfo.R = GetImmString(_typeName, DisInfo.Immediate); - return; - } - if (Op == OP_ADD) { - _line = _name + " := " + _name + " + " + GetImmString(_typeName, DisInfo.Immediate) + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SUB) { - _line = _name + " := " + _name + " - " + GetImmString(_typeName, DisInfo.Immediate) + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_TEST) { - if (_kind == ikSet) { - CmpInfo.L = GetSetString(_typeName, (BYTE*)&DisInfo.Immediate); - CmpInfo.O = CmpOp + 12; - CmpInfo.R = _name; - return; - } - if (_kind == ikInteger) { - CmpInfo.L = GetImmString(_typeName, DisInfo.Immediate); - CmpInfo.O = CmpOp; - CmpInfo.R = _name; - return; - } - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateInstr2MemReg(DWORD curAdr, BYTE Op) { - bool _vmt; - BYTE _kind, _kind1, _kind2; - int _reg2Idx, _offset, _foffset, _pow2, _mod, _size, _idx, _idx1, _classSize, _ap; - DWORD _vmtAdr, _adr; - ITEM _itemSrc, _itemDst, _itemBase, _itemIndx; - ITEM _item, _item1, _item2; - PInfoRec _recN, _recN1; - PLOCALINFO _locInfo; - PFIELDINFO _fInfo; - String _name, _value, _typeName, _line, _comment, _imm, _iname, _fname, _key; - - _reg2Idx = DisInfo.OpRegIdx[1]; - GetRegItem(_reg2Idx, &_itemSrc); - - _value = GetDecompilerRegisterName(_reg2Idx); - if (_itemSrc.Value != "") - _value = _itemSrc.Value; - - GetMemItem(curAdr, &_itemDst, Op); - _name = "?"; - if (_itemDst.Value != "") { - _name = _itemDst.Value; - if (_itemDst.Name != "" && !SameText(_name, _itemDst.Name)) - _name += "{" + _itemDst.Name + "}"; - } - else if (_itemDst.Name != "") { - _name = _itemDst.Name; - } - - if (_itemDst.Flags & IF_STACK_PTR) { - if (Op == OP_MOV) { - if (_itemSrc.Flags & IF_CALL_RESULT) { - _itemSrc.Flags &= ~IF_CALL_RESULT; - _itemSrc.Value = Env->GetLvarName(_itemDst.IntValue, ""); - SetRegItem(_reg2Idx, &_itemSrc); - } - else { - if (!(_itemSrc.Flags & IF_ARG)) - _itemSrc.Name = Env->GetLvarName(_itemDst.IntValue, ""); - } - - Env->Stack[_itemDst.IntValue] = _itemSrc; - _line = _name + " := " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_ADD) { - _line = _name + " := " + _name + " + " + _value + ";"; - Env->AddToBody(_line); - Env->Stack[_itemDst.IntValue].Value = _name + " + " + _value; - return; - } - if (Op == OP_SUB) { - _line = _name + " := " + _name + " - " + _value + ";"; - Env->AddToBody(_line); - Env->Stack[_itemDst.IntValue].Value = _name + " - " + _value; - return; - } - if (Op == OP_TEST) { - CmpInfo.L = _name + " And " + _value; - CmpInfo.O = CmpOp; - CmpInfo.R = 0; - return; - } - if (Op == OP_XOR) { - _line = _name + " := " + _name + " Xor " + _value + ";"; - Env->AddToBody(_line); - Env->Stack[_itemDst.IntValue].Value = _name + " Xor " + _value; - return; - } - if (Op == OP_BT) { - CmpInfo.L = _name + "[" + _value + "]"; - CmpInfo.O = CmpOp; - CmpInfo.R = "True"; - return; - } - } - if (_itemDst.Flags & IF_INTVAL) { - _offset = _itemDst.IntValue; - _ap = Adr2Pos(_offset); - _recN = GetInfoRec(_offset); - if (_recN) - MakeGvar(_recN, _offset, curAdr); - if (_ap >= 0) { - _adr = *(DWORD*)(Code + _ap); - // May be pointer to var - if (IsValidImageAdr(_adr)) { - _recN = GetInfoRec(_adr); - if (_recN) { - MakeGvar(_recN, _offset, _adr); - _line = "^"; - } - } - } - if (_recN) { - if (_itemSrc.Type != "") - _recN->type = _itemSrc.Type; - _name = _recN->GetName(); - } - /* - if (Op == OP_MOV) - { - _ap = Adr2Pos(_offset); _recN = GetInfoRec(_offset); - if (_ap >= 0) - { - _adr = *(DWORD*)(Code + _ap); - //May be pointer to var - if (IsValidImageAdr(_adr)) - { - _recN1 = GetInfoRec(_adr); - if (_recN1) - { - MakeGvar(_recN1, _offset, curAdr); - if (_itemSrc.Type != "") _recN1->type = _itemSrc.Type; - _line = "^" + _recN1->GetName() + " := " + _value + ";"; - Env->AddToBody(_line); - return; - } - } - } - if (_recN) - { - MakeGvar(_recN, _offset, curAdr); - if (_itemSrc.Type != "") _recN->type = _itemSrc.Type; - _line = _recN->GetName() + " := " + _value + ";"; - Env->AddToBody(_line); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); - } - */ - } - if (Op == OP_MOV) { - _line = _name + " := "; - _typeName = _itemDst.Type; - if (_typeName != "") { - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikSet) { - _line += GetSetString(_typeName, (BYTE*)&_itemSrc.IntValue) + ";"; - Env->AddToBody(_line); - return; - } - } - _line += GetDecompilerRegisterName(_reg2Idx) + ";"; - if (_value != "") - _line += "//" + _value; - Env->AddToBody(_line); - return; - } - if (Op == OP_ADD) { - _line = _name + " := " + _name + " + " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_SUB) { - _line = _name + " := " + _name + " - " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_OR) { - _line = _name + " := " + _name + " Or " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_XOR) { - _line = _name + " := " + _name + " Xor " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_TEST) { - CmpInfo.L = _name + " And " + _value; - CmpInfo.O = CmpOp; - CmpInfo.R = 0; - _line = _name + " := " + _name + " And " + _value + ";"; - Env->AddToBody(_line); - return; - } - if (Op == OP_BT) { - CmpInfo.L = _value; - CmpInfo.O = 'Q'; - CmpInfo.R = _name; - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -// Simulate instruction with 2 operands -void __fastcall TDecompiler::SimulateInstr2(DWORD curAdr, BYTE Op) { - if (DisInfo.OpType[0] == otREG) { - if (DisInfo.OpType[1] == otIMM) { - SimulateInstr2RegImm(curAdr, Op); - return; - } - if (DisInfo.OpType[1] == otREG) { - SimulateInstr2RegReg(curAdr, Op); - return; - } - if (DisInfo.OpType[1] == otMEM) { - SimulateInstr2RegMem(curAdr, Op); - return; - } - } - if (DisInfo.OpType[0] == otMEM) { - if (DisInfo.OpType[1] == otIMM) { - SimulateInstr2MemImm(curAdr, Op); - return; - } - if (DisInfo.OpType[1] == otREG) { - SimulateInstr2MemReg(curAdr, Op); - return; - } - } -} - -// --------------------------------------------------------------------------- -// Simulate instruction with 3 operands -void __fastcall TDecompiler::SimulateInstr3(DWORD curAdr, BYTE Op) { - int _reg1Idx, _reg2Idx, _imm; - ITEM _itemDst, _itemSrc; - String _value, _line, _comment; - - _reg1Idx = DisInfo.OpRegIdx[0]; - _reg2Idx = DisInfo.OpRegIdx[1]; - _imm = DisInfo.Immediate; - - InitItem(&_itemDst); - _itemDst.Type = "Integer"; - - if (Op == OP_IMUL) { - // mul reg, reg, imm - if (DisInfo.OpType[1] == otREG) { - _value = String(_imm) + " * " + GetDecompilerRegisterName(_reg2Idx); - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _value; - GetRegItem(_reg2Idx, &_itemSrc); - _comment = String(_imm) + " * " + GetString(&_itemSrc, PRECEDENCE_MULT); - _itemDst.Precedence = PRECEDENCE_MULT; - _itemDst.Value = _comment; - SetRegItem(_reg1Idx, &_itemDst); - Env->AddToBody(_line + ";//" + _comment); - return; - } - // mul reg, [Mem], imm - if (DisInfo.OpType[1] == otMEM) { - GetMemItem(curAdr, &_itemSrc, Op); - _value = String(_imm) + " * " + _itemSrc.Name; - _line = GetDecompilerRegisterName(_reg1Idx) + " := " + _value; - _comment = String(_imm) + " * " + GetString(&_itemSrc, PRECEDENCE_MULT); - _itemDst.Precedence = PRECEDENCE_MULT; - _itemDst.Value = _comment; - SetRegItem(_reg1Idx, &_itemDst); - Env->AddToBody(_line + ";//" + _comment); - return; - } - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -DWORD __fastcall TDecompiler::DecompileTry(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo) { - BYTE op; - int pos, tpos, pos1, instrLen, skipNum; - DWORD startTryAdr, endTryAdr, startFinallyAdr, endFinallyAdr, endExceptAdr, adr, endAdr, hAdr; - PInfoRec recN; - ITEM item; - TDecompiler *de; - - skipNum = IsTryBegin(fromAdr, &startTryAdr) + IsTryBegin0(fromAdr, &startTryAdr); - adr = startTryAdr; - pos = Adr2Pos(adr); - - if (IsFlagSet(cfFinally, pos)) { - // jmp @HandleFinally - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, 0, 0); - adr += instrLen; - pos += instrLen; - // jmp @2 - Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - startFinallyAdr = DisInfo.Immediate; - // Get prev push - pos1 = GetNearestUpInstruction(Adr2Pos(DisInfo.Immediate)); - Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &DisInfo, 0); - endFinallyAdr = DisInfo.Immediate; - // Find flag cfFinally - while (1) { - pos1--; - if (IsFlagSet(cfFinally, pos1)) - break; - } - if (pos1) - endTryAdr = Pos2Adr(pos1); - if (!endTryAdr) { - Env->ErrAdr = fromAdr; - throw Exception("Invalid end address of try section"); - } - // Decompile try - Env->AddToBody("try"); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(endTryAdr); - try { - endAdr = de->Decompile(fromAdr + skipNum, flags, loopInfo); - } - catch (Exception &exception) { - delete de; - throw Exception("Try->" + exception.Message); - } - delete de; - - Env->AddToBody("finally"); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(endFinallyAdr); - try { - endAdr = de->Decompile(startFinallyAdr, CF_FINALLY, loopInfo); - } - catch (Exception &exception) { - delete de; - throw Exception("Try->" + exception.Message); - } - Env->AddToBody("end"); - delete de; - return endAdr; - } - else if (IsFlagSet(cfExcept, pos)) { - // Prev jmp - pos1 = GetNearestUpInstruction(pos); - Disasm.Disassemble(Code + pos1, (__int64)Pos2Adr(pos1), &DisInfo, 0); - endExceptAdr = DisInfo.Immediate; - // Next - pos += Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), &DisInfo, 0); - // Find prev flag cfExcept - while (1) { - if (IsFlagSet(cfExcept, pos1)) - break; - pos1--; - } - if (pos1) - endTryAdr = Pos2Adr(pos1); - if (!endTryAdr) { - Env->ErrAdr = fromAdr; - throw Exception("Invalid end address of try section"); - } - // Decompile try - Env->AddToBody("try"); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(endTryAdr); - try { - endAdr = de->Decompile(fromAdr + 14, 0, loopInfo); - } - catch (Exception &exception) { - delete de; - throw Exception("Try->" + exception.Message); - } - delete de; - // on except - if (IsFlagSet(cfETable, pos)) { - Env->AddToBody("except"); - int num = *((DWORD*)(Code + pos)); - pos += 4; - // Table pos - tpos = pos; - for (int n = 0; n < num; n++) { - adr = *((DWORD*)(Code + pos)); - pos += 4; - if (IsValidCodeAdr(adr)) { - recN = GetInfoRec(adr); - InitItem(&item); - item.Value = "E"; - item.Type = recN->GetName(); - SetRegItem(16, &item); // eax -> exception info - Env->AddToBody("on E:" + recN->GetName() + " do"); - } - else { - Env->AddToBody("else"); - } - hAdr = *((DWORD*)(Code + pos)); - pos += 4; - if (IsValidCodeAdr(hAdr)) { - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - pos1 = tpos; - for (int m = 0; m < num; m++) { - pos1 += 4; - adr = *((DWORD*)(Code + pos1)); - pos1 += 4; - de->SetStop(adr); - } - de->ClearStop(hAdr); - de->SetStop(endExceptAdr); - try { - Env->AddToBody("begin"); - endAdr = de->Decompile(hAdr, 0, loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("Try->" + exception.Message); - } - delete de; - } - } - Env->AddToBody("end"); - } - // except - else { - Env->AddToBody("except"); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(endExceptAdr); - try { - endAdr = de->Decompile(Pos2Adr(pos), CF_EXCEPT, loopInfo); - } - catch (Exception &exception) { - delete de; - throw Exception("Try->" + exception.Message); - } - Env->AddToBody("end"); - delete de; - } - return endAdr; // endExceptAdr; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::MarkCaseEnum(DWORD fromAdr) { - BYTE b; - DWORD adr = fromAdr, jAdr; - int n, pos = Adr2Pos(fromAdr), cTblPos, jTblPos; - - // cmp reg, Imm - // Imm - - int instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - int caseNum = DisInfo.Immediate + 1; - pos += instrLen; - adr += instrLen; - // ja EndOfCaseAdr - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - DWORD endOfCaseAdr = DisInfo.Immediate; - - pos += instrLen; - adr += instrLen; - // mov??? - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - BYTE op = Disasm.GetOp(DisInfo.Mnem); - DWORD cTblAdr = 0, jTblAdr = 0; - if (op == OP_MOV) { - cTblAdr = DisInfo.Offset; - pos += instrLen; - adr += instrLen; - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - } - jTblAdr = DisInfo.Offset; - int maxN = 0; - if (cTblAdr) { - cTblPos = Adr2Pos(cTblAdr); - int cNum = jTblAdr - cTblAdr; - for (n = 0; n < cNum; n++) { - b = *(Code + cTblPos); - if (b > maxN) - maxN = b; - cTblPos++; - } - jTblPos = Adr2Pos(jTblAdr); - for (n = 0; n <= maxN; n++) { - jAdr = *((DWORD*)(Code + jTblPos)); - SetStop(jAdr); - jTblPos += 4; - } - } - else { - jTblPos = Adr2Pos(jTblAdr); - for (n = 0; n < caseNum; n++) { - if (IsFlagSet(cfCode | cfLoc, jTblPos)) - break; - jAdr = *((DWORD*)(Code + jTblPos)); - SetStop(jAdr); - jTblPos += 4; - } - } -} - -// --------------------------------------------------------------------------- -DWORD __fastcall TDecompiler::DecompileCaseEnum(DWORD fromAdr, int N, PLoopInfo loopInfo) { - bool skip; - BYTE b; - DWORD adr = fromAdr, jAdr, jAdr1, _adr, _endAdr = 0; - int n, m, pos = Adr2Pos(fromAdr), cTblPos, cTblPos1, jTblPos, jTblPos1; - ITEM item, item1; - String line = ""; - TDecompiler *de; - - // cmp reg, Imm - // Imm - - int instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - int caseNum = DisInfo.Immediate + 1; - pos += instrLen; - adr += instrLen; - // ja EndOfCaseAdr - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - DWORD endOfCaseAdr = DisInfo.Immediate; - - pos += instrLen; - adr += instrLen; - // mov??? - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - BYTE op = Disasm.GetOp(DisInfo.Mnem); - DWORD cTblAdr = 0, jTblAdr = 0; - if (op == OP_MOV) { - cTblAdr = DisInfo.Offset; - pos += instrLen; - adr += instrLen; - instrLen = Disasm.Disassemble(Code + pos, (__int64)adr, &DisInfo, 0); - } - jTblAdr = DisInfo.Offset; - int maxN = 0; - if (cTblAdr) { - cTblPos = Adr2Pos(cTblAdr); - int cNum = jTblAdr - cTblAdr; - for (n = 0; n < cNum; n++) { - b = *(Code + cTblPos); - if (b > maxN) - maxN = b; - cTblPos++; - } - jTblPos = Adr2Pos(jTblAdr); - for (m = 0; m <= maxN; m++) { - line = ""; - skip = false; - cTblPos = Adr2Pos(cTblAdr); - for (n = 0; n < cNum; n++) { - b = *(Code + cTblPos); - jAdr = *((DWORD*)(Code + jTblPos)); - if (b == m) { - if (jAdr == endOfCaseAdr) { - skip = true; - break; - } - if (line != "") - line += ","; - line += String(n + N); - } - cTblPos++; - } - if (!skip) { - Env->AddToBody(line + ":"); - Env->SaveContext(endOfCaseAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(endOfCaseAdr); - de->MarkCaseEnum(fromAdr); - de->ClearStop(jAdr); - - try { - Env->AddToBody("begin"); - _adr = de->Decompile(jAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("CaseEnum->" + exception.Message); - } - Env->RestoreContext(endOfCaseAdr); - delete de; - } - jTblPos += 4; - } - return _endAdr; // endOfCaseAdr; - } - jTblPos = Adr2Pos(jTblAdr); - for (n = 0; n < caseNum; n++) { - if (IsFlagSet(cfCode | cfLoc, jTblPos)) - break; - jAdr = *((DWORD*)(Code + jTblPos)); - if (jAdr != endOfCaseAdr) { - skip = false; - // If case already decompiled? - jTblPos1 = Adr2Pos(jTblAdr); - for (m = 0; m < n; m++) { - jAdr1 = *((DWORD*)(Code + jTblPos1)); - if (jAdr1 == jAdr) { - skip = true; - break; - } - jTblPos1 += 4; - } - - if (!skip) { - line = ""; - jTblPos1 = Adr2Pos(jTblAdr); - for (m = 0; m < caseNum; m++) { - if (IsFlagSet(cfCode | cfLoc, jTblPos1)) - break; - jAdr1 = *((DWORD*)(Code + jTblPos1)); - if (jAdr1 == jAdr) { - if (line != "") - line += ","; - line += String(m + N); - } - jTblPos1 += 4; - } - Env->AddToBody(line + ":"); - Env->SaveContext(endOfCaseAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(endOfCaseAdr); - de->MarkCaseEnum(fromAdr); - de->ClearStop(jAdr); - - try { - Env->AddToBody("begin"); - _adr = de->Decompile(jAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("CaseEnum->" + exception.Message); - } - Env->RestoreContext(endOfCaseAdr); - delete de; - } - } - jTblPos += 4; - } - return _endAdr; // endOfCaseAdr; -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompiler::GetSysCallAlias(String AName) { - if (SameText(AName, "@Assign") || SameText(AName, "@AssignText")) - return "AssignFile"; - if (SameText(AName, "@Append")) - return "Append"; - if (SameText(AName, "@Assert")) - return "Assert"; - if (SameText(AName, "@BlockRead")) - return "Read"; - if (SameText(AName, "@BlockWrite")) - return "Write"; - if (SameText(AName, "@ChDir")) - return "ChDir"; - if (SameText(AName, "@Close")) - return "CloseFile"; - if (SameText(AName, "@DynArrayHigh")) - return "High"; - if (SameText(AName, "@EofText")) - return "Eof"; - if (SameText(AName, "@FillChar")) - return "FillChar"; - if (SameText(AName, "@Flush")) - return "Flush"; - if (SameText(AName, "@Copy") || SameText(AName, "@LStrCopy") || SameText(AName, "@WStrCopy") || SameText(AName, "@UStrCopy")) - return "Copy"; - if (SameText(AName, "@LStrDelete") || SameText(AName, "@UStrDelete")) - return "Delete"; - if (SameText(AName, "@LStrFromPCharLen")) - return "SetString"; - if (SameText(AName, "@LStrInsert")) - return "Insert"; - if (SameText(AName, "@PCharLen") || SameText(AName, "@LStrLen") || SameText(AName, "@WStrLen") || SameText(AName, "@UStrLen")) - return "Length"; - if (SameText(AName, "@LStrOfChar")) - return "StringOfChar"; - if (SameText(AName, "@Pos") || SameText(AName, "@LStrPos") || SameText(AName, "@WStrPos") || SameText(AName, "@UStrPos")) - return "Pos"; - if (SameText(AName, "@LStrSetLength") || SameText(AName, "@UStrSetLength")) - return "SetLength"; - if (SameText(AName, "@MkDir")) - return "MkDir"; - if (SameText(AName, "@New")) - return "New"; - if (SameText(AName, "@RaiseAgain")) - return "Raise"; - if (SameText(AName, "@RandInt")) - return "Random"; - if (SameText(AName, "@ReadLn")) - return "ReadLn"; - if (SameText(AName, "@ReadLong") || SameText(AName, "@ReadLString") || SameText(AName, "@ReadRec") || SameText(AName, "@ReadUString")) - return "Read"; - if (SameText(AName, "@ReallocMem")) - return "ReallocMem"; - if (SameText(AName, "@ResetFile") || SameText(AName, "@ResetText")) - return "Reset"; - if (SameText(AName, "@ValLong") || SameText(AName, "@ValInt64")) - return "Val"; - if (SameText(AName, "@WriteLn")) - return "WriteLn"; - return ""; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompiler::SimulateSysCall(String name, DWORD procAdr, int instrLen) { - int _cnt, _esp, _cmpRes, _size; - DWORD _adr; - ITEM _item, _item1, _item2, _item3, _item4; - PInfoRec _recN; - String _line, _value, _value1, _value2, _typeName, _op; - __int64 _int64Val; - - if (SameText(name, "@AsClass")) { - // type of edx -> type of eax - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - _item1.Value = _item2.Type + "(" + _item1.Value + ")"; - _item1.Type = _item2.Type; - SetRegItem(16, &_item1); - return false; - } - if (SameText(name, "@IsClass")) { - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - _adr = _item2.IntValue; - if (!IsValidImageAdr(_adr)) { - throw Exception("Invalid address"); - } - _recN = GetInfoRec(_adr); - InitItem(&_item); - _item.Value = "(" + _item1.Value + " is " + _recN->GetName() + ")"; - _item.Type = "Boolean"; - SetRegItem(16, &_item); - return false; - } - if (SameText(name, "@CopyRecord")) { - // dest:Pointer - GetRegItem(16, &_item1); - // source:Pointer - GetRegItem(18, &_item2); - // typeInfo:Pointer - GetRegItem(17, &_item3); - _recN = GetInfoRec(_item3.IntValue); - _typeName = _recN->GetName(); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); - _item1 = Env->Stack[_item1.IntValue]; - } - Env->Stack[_item1.IntValue].Type = _typeName; - - _line = _item1.Value + " := " + _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@DynArrayAsg")) { - // eax - dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - if (Env->Stack[_item1.IntValue].Value == "") - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, "array of"); - _item1 = Env->Stack[_item1.IntValue]; - } - // edx - src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - if (Env->Stack[_item2.IntValue].Value == "") - Env->Stack[_item2.IntValue].Value = Env->GetLvarName(_item2.IntValue, "array of"); - _item2 = Env->Stack[_item2.IntValue]; - } - _line = _item1.Value + " := " + _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@DynArrayClear")) { - // eax - var - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - if (Env->Stack[_item1.IntValue].Value == "") - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, "array of"); - _item1 = Env->Stack[_item1.IntValue]; - } - _line = _item1.Value + " := Nil;"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@DynArrayLength")) { - // eax - ptr - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - if (Env->Stack[_item1.IntValue].Value == "") - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, "array of"); - _item1 = Env->Stack[_item1.IntValue]; - } - _value = "Length(" + _item1.Value + ")"; - _line = "EAX := " + _value; - Env->AddToBody(_line); - InitItem(&_item); - _item.Flags |= IF_CALL_RESULT; - _item.Value = _value; - _item.Type = "Integer"; - SetRegItem(16, &_item); - return false; - } - if (SameText(name, "@DynArraySetLength")) // stdcall - { - // eax - dst - GetRegItem(16, &_item1); - _item = _item1; - // edx - type of DynArray - GetRegItem(18, &_item2); - _typeName = GetTypeName(_item2.IntValue); - if (_item1.Flags & IF_STACK_PTR) { - if (Env->Stack[_item1.IntValue].Value == "") - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); - _item = Env->Stack[_item1.IntValue]; - Env->Stack[_item1.IntValue].Type = _typeName; - _line = "SetLength(" + _item.Value; - } - else if (_item1.Flags & IF_INTVAL) { - _line = "SetLength(" + MakeGvarName(_item1.IntValue); - } - // ecx - dims cnt - GetRegItem(17, &_item3); - _cnt = _item3.IntValue; - _esp = _ESP_; - for (int n = 0; n < _cnt; n++) { - _line += ", "; - _item = Env->Stack[_esp]; - if (_item.Flags & IF_INTVAL) - _line += String(_item.IntValue); - else - _line += _item.Value; - _esp += 4; - } - _line += ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@FreeMem")) { - _line = "FreeMem("; - GetRegItem(16, &_item); - if (_item.Value != "") - _line += _item.Value; - else - _line += "EAX"; - _line += ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@GetMem")) { - _value = "GetMem("; - // eax-Bytes - GetRegItem(16, &_item); - if (_item.Flags & IF_INTVAL) - _value += String(_item.IntValue); - else - _value += _item.Value; - _value += ")"; - _line = _value + ";"; - Env->AddToBody(_line); - - _typeName = ManualInput(CurProcAdr, procAdr, "Define type of function GetMem", "Type:"); - if (_typeName == "") { - Env->ErrAdr = procAdr; - throw Exception("Bye!"); - } - - InitItem(&_item); - _item.Flags |= IF_CALL_RESULT; - _item.Value = _value; - _item.Type = _typeName; - SetRegItem(16, &_item); - return false; - } - if (SameText(name, "@Halt0")) { - // _line = "Exit;"; - // Env->AddToBody(_line); - return false; - } - if (SameText(name, "@InitializeRecord") || SameText(name, "@FinalizeRecord") || SameText(name, "@AddRefRecord")) { - // eax - dst - GetRegItem(16, &_item1); - // edx - TypeInfo - GetRegItem(18, &_item2); - if (_item1.Flags & IF_STACK_PTR) { - _typeName = GetTypeName(_item2.IntValue); - _size = GetRecordSize(_typeName); - for (int r = 0; r < _size; r++) { - if (_item1.IntValue + r >= Env->StackSize) { - Env->ErrAdr = procAdr; - throw Exception("Possibly incorrect RecordSize (or incorrect type of record)"); - } - _item = Env->Stack[_item1.IntValue + r]; - _item.Flags = IF_FIELD; - _item.Offset = r; - _item.Type = ""; - if (r == 0) - _item.Type = _typeName; - Env->Stack[_item1.IntValue + r] = _item; - } - if (Env->Stack[_item1.IntValue].Value == "") - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); - Env->Stack[_item1.IntValue].Type = _typeName; - } - return false; - } - if (SameText(name, "@InitializeArray") || SameText(name, "@FinalizeArray")) { - // eax - dst - GetRegItem(16, &_item1); - _item = _item1; - // edx - type of DynArray - GetRegItem(18, &_item2); - // ecx - dims cnt - GetRegItem(17, &_item3); - _cnt = _item3.IntValue; - _typeName = "array [1.." + String(_cnt) + "] of " + GetTypeName(_item2.IntValue); - if (_item1.Flags & IF_STACK_PTR) { - if (Env->Stack[_item1.IntValue].Value == "") - Env->Stack[_item1.IntValue].Value = Env->GetLvarName(_item1.IntValue, _typeName); - _item = Env->Stack[_item1.IntValue]; - } - Env->Stack[_item1.IntValue].Type = _typeName; - return false; - } - if (SameText(name, "@IntfCast")) { - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - _line = "(" + _item1.Value + " as " + _item2.Value1 + ")"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@IntfClear")) { - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "IInterface"; - - _line = _item1.Value + " := Nil;"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@IntfCopy")) { - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - _line = _item1.Value + " := " + _item2.Value1; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrAsg") || SameText(name, "@LStrLAsg") || SameText(name, "@WStrAsg") || SameText(name, "@WStrLAsg") || SameText(name, "@UStrAsg") || SameText(name, "@UStrLAsg")) { - // eax - dst - GetRegItem(16, &_item1); - // edx - src - GetRegItem(18, &_item2); - _line = GetStringArgument(&_item1) + " := " + GetStringArgument(&_item2) + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrCat") || SameText(name, "@WStrCat") || SameText(name, "@UStrCat")) { - // eax - dst - GetRegItem(16, &_item); - _line = GetStringArgument(&_item) + " := " + GetStringArgument(&_item) + " + "; - // edx - src - GetRegItem(18, &_item); - _line += GetStringArgument(&_item) + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrCat3") || SameText(name, "@WStrCat3") || SameText(name, "@UStrCat3")) { - // eax - dst - GetRegItem(16, &_item); - _line = GetStringArgument(&_item) + " := "; - // edx - str1 - GetRegItem(18, &_item); - _line += GetStringArgument(&_item) + " + "; - // ecx - str2 - GetRegItem(17, &_item); - _line += GetStringArgument(&_item) + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrCatN") || SameText(name, "@WStrCatN") || SameText(name, "@UStrCatN")) { - // eax - dst - GetRegItem(16, &_item); - _line = GetStringArgument(&_item) + " := "; - if (_item.Flags & IF_STACK_PTR) { - Env->Stack[_item.IntValue].Flags = 0; - Env->Stack[_item.IntValue].Value = Env->GetLvarName(_item.IntValue, "String"); - if (name[2] == 'L') - Env->Stack[_item.IntValue].Type = "AnsiString"; - else if (name[2] == 'W') - Env->Stack[_item.IntValue].Type = "WideString"; - else - Env->Stack[_item.IntValue].Type = "UnicodeString"; - } - // edx - argCnt - GetRegItem(18, &_item2); - _cnt = _item2.IntValue; - _ESP_ += 4 * _cnt; - _esp = _ESP_; - for (int n = 0; n < _cnt; n++) { - if (n) - _line += " + "; - _esp -= 4; - _item = Env->Stack[_esp]; - _line += GetStringArgument(&_item); - } - _line += ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrClr") || SameText(name, "@WStrClr") || SameText(name, "@UStrClr")) { - GetRegItem(16, &_item); - _line = GetStringArgument(&_item) + " := '';"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@AStrCmp") || SameText(name, "@LStrCmp") || SameText(name, "@WStrCmp") || SameText(name, "@UStrCmp") || SameText(name, "@UStrEqual")) { - GetCmpInfo(procAdr + instrLen); - CmpInfo.O = 'F'; // By default (<>) - - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _item1 = Env->Stack[_item1.IntValue]; - CmpInfo.L = _item1.Value; - - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - _item2 = Env->Stack[_item2.IntValue]; - CmpInfo.R = _item2.Value; - } - else if (_item2.Flags & IF_INTVAL) { - if (!_item2.IntValue) - CmpInfo.R = "''"; - else { - _recN = GetInfoRec(_item2.IntValue); - if (_recN) - CmpInfo.R = _recN->GetName(); - else - // Fix it!!! - // Add analyze of String type - CmpInfo.R = TransformString((char*)(Code + Adr2Pos(_item2.IntValue)), -1); - } - } - else { - CmpInfo.R = _item2.Value; - } - return true; - } - if (SameText(name, "@LStrFromArray") || SameText(name, "@LStrFromChar") || SameText(name, "@LStrFromPChar") || SameText(name, "@LStrFromString") || SameText(name, "@LStrFromWStr") || - SameText(name, "@LStrFromUStr")) { - // eax - dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "String"; - } - // edx - src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - if (name[10] == 'A') - _typeName = "PAnsiChar"; - else if (name[10] == 'C') - _typeName = "Char"; - else if (name[10] == 'P') - _typeName = "PChar"; - else if (name[10] == 'S') - _typeName = "ShortString"; - else if (name[10] == 'W') - _typeName = "WideString"; - else if (name[10] == 'U') - _typeName = "UnicodeString"; - - Env->Stack[_item2.IntValue].Type = _typeName; - } - _line = _item1.Value + " := " + _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrToPChar")) { - // eax - src - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "String"; - _item1.Value = "PChar(" + _item1.Value + ")"; - SetRegItem(16, &_item1); - _line = "EAX := " + _item1.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@LStrToString")) { - // eax - dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_INTVAL) { - _line = MakeGvarName(_item1.IntValue); - } - else if (_item1.Flags & IF_STACK_PTR) { - _line = _item1.Value; - Env->Stack[_item1.IntValue].Type = "ShortString"; - } - // edx - src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) - Env->Stack[_item2.IntValue].Type = "String"; - _line += " := " + _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@PStrNCat") || SameText(name, "@PStrCpy") || SameText(name, "@PStrNCpy")) { - // eax - dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "ShortString"; - // edx - src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) - Env->Stack[_item2.IntValue].Type = "ShortString"; - _line = _item1.Value + " := "; - if (SameText(name, "@PStrNCat")) - _line += _item1.Value + " + "; - _line += _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@RaiseExcept")) { - // eax - Exception - GetRegItem(16, &_item1); - _line = "raise " + _item1.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@RewritFile") || SameText(name, "@RewritText")) { - // File - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _item1 = Env->Stack[_item1.IntValue]; - _line = "Rewrite(" + ExtractClassName(_item1.Value) + ");"; - Env->AddToBody(_line); - return false; - } - - if (SameText(name, "@Sin") || SameText(name, "@Cos") || SameText(name, "@Exp") || SameText(name, "@Int")) { - _value = name.SubString(2, 5); - InitItem(&_item1); - _item1.Value = _value + "(" + FGet(0)->Value + ")"; - _item1.Type = "Extended"; - FSet(0, &_item1); - return false; - } - if (SameText(name, "@Trunc") || SameText(name, "@Round")) { - _value = name.SubString(2, 5) + "(" + FGet(0)->Value + ")"; - InitItem(&_item); - _item.Value = _value; - _item.Type = "Int64"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "//EAX := " + _value + ";"; - Env->AddToBody(_line); - FPop(); - return false; - } - if (SameText(name.SubString(1, name.Length() - 1), "@UniqueString")) { - GetRegItem(16, &_item1); - InitItem(&_item); - _item.Value = "EAX"; - _item.Type = "String"; - SetRegItem(16, &_item); - if (_item1.Flags & IF_STACK_PTR) { - _value = "UniqueString(" + Env->Stack[_item1.IntValue].Value + ")"; - Env->Stack[_item1.IntValue].Type = "String"; - _line = "//EAX := " + _value; - Env->AddToBody(_line); - return false; - } - _value = "UniqueString(" + _item1.Value + ")"; - _line = "//EAX := " + _value; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrFromChar") || SameText(name, "@UStrFromWChar")) { - // eax-Dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - } - // edx-Src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - if (name[11] == 'C') - Env->Stack[_item2.IntValue].Type = "Char"; - else - Env->Stack[_item2.IntValue].Type = "WideChar"; - } - _line = _item1.Value + " := " + _item2.Value; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrFromLStr")) { - // eax-Dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - } - // edx-Src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - Env->Stack[_item2.IntValue].Type = "AnsiString"; - } - _line = _item1.Value + " := " + _item2.Value; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrFromString")) { - // eax - dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - } - // edx - src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - Env->Stack[_item2.IntValue].Type = "ShortString"; - } - _line = _item1.Value + " := " + _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrFromWStr")) { - // eax-Dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - } - // edx-Src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - Env->Stack[_item2.IntValue].Type = "WideString"; - } - _line = _item1.Value + " := " + _item2.Value; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrFromPWChar")) { - // eax - Dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - } - // edx-Src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - Env->Stack[_item2.IntValue].Type = "PWideChar"; - } - _line = _item1.Value + " := " + _item2.Value; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@WStrToPWChar")) { - // eax - src - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "WideString"; - } - _item1.Value = "PWideChar(" + _item1.Value + ")"; - _item1.Type = "PWideChar"; - SetRegItem(16, &_item1); - _line = "EAX := " + _item1.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrToPWChar")) { - // eax - src - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - } - _item1.Value = "PWideChar(" + _item1.Value + ")"; - _item1.Type = "PWideChar"; - SetRegItem(16, &_item1); - _line = "EAX := " + _item1.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@UStrToString")) { - // eax - dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "UnicodeString"; - // edx - src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) - Env->Stack[_item2.IntValue].Type = "String"; - _line = _item1.Value + " := " + _item2.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarClear")) { - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "Variant"; - _line = _item1.Value + " := 0;"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarAdd") || SameText(name, "@VarSub") || SameText(name, "@VarMul") || SameText(name, "@VarDiv") || SameText(name, "@VarMod") || SameText(name, "@VarAnd") || SameText(name, - "@VarOr") || SameText(name, "@VarXor") || SameText(name, "@VarShl") || SameText(name, "@VarShr") || SameText(name, "@VarRDiv")) { - _op = name.SubString(5, name.Length()); - - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "Variant"; - _item1 = Env->Stack[_item1.IntValue]; - } - if (_item2.Flags & IF_STACK_PTR) { - Env->Stack[_item2.IntValue].Type = "Variant"; - _item2 = Env->Stack[_item2.IntValue]; - } - _line = _item1.Name + " := " + _item1.Name + " " + _op + " " + _item2.Name + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarNeg") || SameText(name, "@VarNot")) { - _op = name.SubString(5, name.Length()); - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "Variant"; - _item1 = Env->Stack[_item1.IntValue]; - } - _line = _item1.Name + " := " + _op + " " + _item1.Name + ";"; - Env->AddToBody(_line); - return false; - } - - if (SameText(name.SubString(1, 7), "@VarCmp")) { - GetCmpInfo(procAdr + instrLen); - if (name[8] == 'E' && name[9] == 'Q') - CmpInfo.O = 'E'; // JZ - else if (name[8] == 'N' && name[9] == 'E') - CmpInfo.O = 'F'; // JNZ - else if (name[8] == 'L') { - if (name[9] == 'E') - CmpInfo.O = 'O'; // JLE - else if (name[9] == 'T') - CmpInfo.O = 'M'; // JL - } - else if (name[8] == 'G') { - if (name[9] == 'E') - CmpInfo.O = 'N'; // JGE - else if (name[9] == 'T') - CmpInfo.O = 'P'; // JG - } - - GetRegItem(16, &_item1); // eax - Left argument - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "Variant"; - _item1 = Env->Stack[_item1.IntValue]; - } - CmpInfo.L = _item1.Name; - - GetRegItem(18, &_item2); // edx - Right argument - if (_item2.Flags & IF_STACK_PTR) { - Env->Stack[_item2.IntValue].Type = "Variant"; - _item2 = Env->Stack[_item2.IntValue]; - } - CmpInfo.R = _item2.Name; - return true; - } - // Cast to Variant - if (SameText(name, "@VarFromBool") || SameText(name, "@VarFromInt") || SameText(name, "@VarFromPStr") || SameText(name, "@VarFromLStr") || SameText(name, "@VarFromWStr") || SameText(name, - "@VarFromUStr") || SameText(name, "@VarFromDisp")) { - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "Variant"; - _item1 = Env->Stack[_item1.IntValue]; - } - GetRegItem(18, &_item2); - _line = _item1.Name + " := Variant(" + _item2.Name + ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarFromTDateTime") || SameText(name, "@VarFromCurr")) { - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - Env->Stack[_item1.IntValue].Type = "Variant"; - _item1 = Env->Stack[_item1.IntValue]; - } - _line = _item1.Name + " := Variant(" + FPop()->Value + ")"; // FGet(0) - Env->AddToBody(_line); - // FPop(); - return false; - } - if (SameText(name, "@VarFromReal")) { - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _line = Env->GetLvarName(_item1.IntValue, "Variant"); - _line += " := Variant(" + FPop()->Value + ")"; // ??? - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarToInt")) { - // eax=Variant, return Integer - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "Variant"; - InitItem(&_item); - _item.Value = "Integer(" + Env->GetLvarName(_item1.IntValue, "Variant") + ")"; - SetRegItem(16, &_item); - _line = "EAX := " + _item.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarToInteger")) { - // edx=Variant, eax=Integer - GetRegItem(18, &_item1); - GetRegItem(16, &_item2); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "Variant"; - InitItem(&_item); - _item.Value = "Integer(" + _item1.Value + ")"; - SetRegItem(16, &_item); - _line = Env->GetLvarName(_item2.IntValue, "Variant") + " := " + _item.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarToLStr")) { - // edx=Variant, eax=String - GetRegItem(18, &_item1); - GetRegItem(16, &_item2); - - if (_item2.Flags & IF_INTVAL) // !!!Use it for other cases!!! - { - _line = MakeGvarName(_item2.IntValue); - } - else if (_item2.Flags & IF_STACK_PTR) { - _line = Env->GetLvarName(_item2.IntValue, "String"); - Env->Stack[_item2.IntValue].Type = "String"; - } - else { - _line = _item2.Value; - } - - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "Variant"; - InitItem(&_item); - _item.Value = "String(" + _item1.Value + ")"; - SetRegItem(16, &_item); - _line += " := " + _item.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@VarToReal")) { - // eax=Variant - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - Env->Stack[_item1.IntValue].Type = "Variant"; - InitItem(&_item); - _item.Value = "Real(" + _item1.Value + ")"; - _item.Type = "Extended"; - FSet(0, &_item); - return false; - } - if (SameText(name, "@Write0Ext")) { - // File - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _item1 = Env->Stack[_item1.IntValue]; - // Value (Extended) - GetFloatItemFromStack(_ESP_, &_item2, FT_EXTENDED); - _ESP_ += 12; - _line = "Write(" + ExtractClassName(_item1.Value) + ", " + _item2.Value + ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@Str0Ext")) { - // Value (Extended) - GetFloatItemFromStack(_ESP_, &_item1, FT_EXTENDED); - _ESP_ += 12; - // Destination - eax - GetRegItem(16, &_item2); - _line = "Str(" + _item1.Value + ", " + _item2.Value + ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@Str1Ext")) { - // Value (Extended) - GetFloatItemFromStack(_ESP_, &_item1, FT_EXTENDED); - _ESP_ += 12; - // Width - eax - GetRegItem(16, &_item2); - // Destination - edx - GetRegItem(18, &_item3); - _line = "Str(" + _item1.Value + ":" + String(_item2.IntValue) + ", " + _item3.Value + ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@Str2Ext")) { - // Value (Extended) - GetFloatItemFromStack(_ESP_, &_item1, FT_EXTENDED); - _ESP_ += 12; - // Width - eax - GetRegItem(16, &_item2); - // Precision - edx - GetRegItem(18, &_item3); - // Destination - ecx - GetRegItem(17, &_item4); - _line = "Str(" + _item1.Value + ":" + String(_item2.IntValue) + ":" + String(_item3.IntValue) + ", " + _item4.Value + ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@Write2Ext")) { - // File - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _item1 = Env->Stack[_item1.IntValue]; - // Value (Extended) - GetFloatItemFromStack(_ESP_, &_item2, FT_EXTENDED); - _ESP_ += 12; - // edx - GetRegItem(18, &_item3); - // ecx - GetRegItem(17, &_item4); - _line = "Write(" + ExtractClassName(_item1.Value) + ", " + _item2.Value + ":" + String(_item3.IntValue) + ":" + String(_item4.IntValue) + ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@Write0Char") || SameText(name, "@Write0WChar") || SameText(name, "@WriteLong") || SameText(name, "@Write0Long")) { - // File - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _item1 = Env->Stack[_item1.IntValue]; - _line = "Write(" + ExtractClassName(_item1.Value) + ", "; - // edx - GetRegItem(18, &_item2); - if (_item2.Flags & IF_INTVAL) - _line += GetImmString(_item2.IntValue); - else - _line += _item2.Value; - _line += ");"; - Env->AddToBody(_line); - return false; - } - if (SameText(name, "@Write0LString") || SameText(name, "@Write0UString")) { - // File - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) - _item1 = Env->Stack[_item1.IntValue]; - // edx - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) - _item2 = Env->Stack[_item2.IntValue]; - _line = "Write(" + ExtractClassName(_item1.Value) + ", " + _item2.Value + ");"; - Env->AddToBody(_line); - return false; - } - - if (SameText(name, "@WStrFromUStr") || SameText(name, "@WStrFromLStr")) { - // eax-Dst - GetRegItem(16, &_item1); - if (_item1.Flags & IF_STACK_PTR) { - _item = Env->Stack[_item1.IntValue]; - _item.Value = Env->GetLvarName(_item1.IntValue, "String"); - _item.Type = "WideString"; - Env->Stack[_item1.IntValue] = _item; - _item1 = _item; - } - // edx-Src - GetRegItem(18, &_item2); - if (_item2.Flags & IF_STACK_PTR) { - _item2 = Env->Stack[_item2.IntValue]; - if (SameText(name, "@WStrFromUStr")) - Env->Stack[_item2.IntValue].Type = "UnicodeString"; - else - Env->Stack[_item2.IntValue].Type = "String"; - } - _line = _item1.Value + " := " + _item2.Value; - Env->AddToBody(_line); - return false; - } - if (name.Pos("@_lldiv") == 1 || SameText(name, "@__lludiv")) { - // Argument (Int64) in edx:eax - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - if (_item1.Flags & IF_INTVAL) { - _int64Val = (_item2.IntValue << 32) | _item1.IntValue; - _value1 = IntToStr(_int64Val); - } - else if (_item1.Flags & IF_STACK_PTR) { - _item1 = Env->Stack[_item1.IntValue]; - _value1 = _item1.Value; - } - else - _value1 = _item1.Value; - - // Argument (Int64) in stack - _item3 = Env->Stack[_ESP_]; - _ESP_ += 4; - _item4 = Env->Stack[_ESP_]; - _ESP_ += 4; - if (_item3.Flags & IF_INTVAL) { - _int64Val = (_item4.IntValue << 32) | _item3.IntValue; - _value2 = IntToStr(_int64Val); - } - else if (_item3.Flags & IF_STACK_PTR) { - _item3 = Env->Stack[_item3.IntValue]; - _value2 = _item3.Value; - } - else - _value2 = _item3.Value; - - InitItem(&_item); - _item.Value = _value1 + " Div " + _value2; - _item.Type = "Int64"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := " + _item.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (name.Pos("@_llmod") == 1 || SameText(name, "@__llumod")) { - // Argument (Int64) in edx:eax - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - if (_item1.Flags & IF_INTVAL) { - _int64Val = (_item2.IntValue << 32) | _item1.IntValue; - _value1 = IntToStr(_int64Val); - } - else if (_item1.Flags & IF_STACK_PTR) { - _item1 = Env->Stack[_item1.IntValue]; - _value1 = _item1.Value; - } - else - _value1 = _item1.Value; - - // Argument (Int64) in stack - _item3 = Env->Stack[_ESP_]; - _ESP_ += 4; - _item4 = Env->Stack[_ESP_]; - _ESP_ += 4; - if (_item3.Flags & IF_INTVAL) { - _int64Val = (_item4.IntValue << 32) | _item3.IntValue; - _value2 = IntToStr(_int64Val); - } - else if (_item3.Flags & IF_STACK_PTR) { - _item3 = Env->Stack[_item3.IntValue]; - _value2 = _item3.Value; - } - else - _value2 = _item3.Value; - - InitItem(&_item); - _item.Value = _value1 + " Mod " + _value2; - _item.Type = "Int64"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := " + _item.Value + ";"; - Env->AddToBody(_line); - return false; - } - if (name.Pos("@_llmul") == 1) { - // Argument (Int64) in edx:eax - GetRegItem(16, &_item1); - GetRegItem(18, &_item2); - if (_item1.Flags & IF_INTVAL) { - _int64Val = (_item2.IntValue << 32) | _item1.IntValue; - _value1 = IntToStr(_int64Val); - } - else if (_item1.Flags & IF_STACK_PTR) { - _item1 = Env->Stack[_item1.IntValue]; - _value1 = _item1.Value; - } - else - _value1 = _item1.Value; - - // Argument (Int64) in stack - _item3 = Env->Stack[_ESP_]; - _ESP_ += 4; - _item4 = Env->Stack[_ESP_]; - _ESP_ += 4; - if (_item3.Flags & IF_INTVAL) { - _int64Val = (_item4.IntValue << 32) | _item3.IntValue; - _value2 = IntToStr(_int64Val); - } - else if (_item3.Flags & IF_STACK_PTR) { - _item3 = Env->Stack[_item3.IntValue]; - _value2 = _item3.Value; - } - else - _value2 = _item3.Value; - - InitItem(&_item); - _item.Value = _value1 + " * " + _value2; - _item.Type = "Int64"; - SetRegItem(16, &_item); - SetRegItem(18, &_item); - _line = "EDX_EAX := " + _item.Value + ";"; - Env->AddToBody(_line); - return false; - } - // No action - if (SameText(name, "@DoneExcept") || SameText(name, "@LStrAddRef") || SameText(name, "@WStrAddRef") || SameText(name, "@UStrAddRef") || SameText(name, "@LStrArrayClr") || SameText(name, - "@WStrArrayClr") || SameText(name, "@UStrArrayClr") || SameText(name, "@VarClr") || SameText(name, "@DynArrayAddRef") || SameText(name, "@EnsureAnsiString") || SameText(name, - "@EnsureUnicodeString") || SameText(name, "@_IOTest") || SameText(name, "@CheckAutoResult") || SameText(name, "@InitExe") || SameText(name, "@InitLib") || SameText(name, "@IntfAddRef")) { - return false; - } - Env->ErrAdr = procAdr; - throw Exception("Under construction"); - return false; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateFormatCall() { - int n, _num = 0, _ofs, _esp; - String _line = "Format("; - ITEM _item; - - // eax - format - GetRegItem(16, &_item); - _line += _item.Value + ", ["; - - // edx - pointer to args - GetRegItem(18, &_item); - _ofs = _item.IntValue; - - // ecx - args num - GetRegItem(17, &_item); - _num = _item.IntValue + 1; - - for (n = 0; n < _num; n++) { - if (n) - _line += ", "; - _line += Env->Stack[_ofs].Value; - _ofs += 5; - } - _line += "]);"; - // Result - _esp = _ESP_; - _ESP_ += 4; - _item = Env->Stack[_esp]; - _line = _item.Value + " := " + _line; - - Env->AddToBody(_line); - Env->LastResString = ""; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::SimulateFloatInstruction(DWORD curAdr, int instrLen) { - bool _vmt, _r, _p, _pp; - int _reg1Idx, _reg2Idx, _offset, _cmpRes, _ea, _sz, _ofs; - char *_pos; - DWORD _dd, _vmtAdr; - ITEM _item, _itemBase, _itemSrc; - PInfoRec _recN; - PFIELDINFO _fInfo; - String _name, _typeName, _val, _line, _lvarName; - - _r = false; - _p = false; - _pp = false; - _dd = *((DWORD*)(DisInfo.Mnem + 1)); - // fild, fld - if (_dd == 'dli' || _dd == 'dl') { - // op Mem - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemSrc.IntValue]; - if (_item.Value == "") { - if (_itemSrc.Value != "") - _item.Value = _itemSrc.Value; - if (_itemSrc.Name != "") - _item.Value = _itemSrc.Name; - } - _item.Precedence = PRECEDENCE_NONE; - FPush(&_item); - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) { - InitItem(&_item); - _item.Value = _recN->GetName(); - _item.Type = _recN->type; - FPush(&_item); - return; - } - } - InitItem(&_item); - if (_itemSrc.Name != "" && !IsDefaultName(_itemSrc.Name)) - _item.Value = _itemSrc.Name; - else - _item.Value = _itemSrc.Value; - _item.Type = _itemSrc.Type; - FPush(&_item); - return; - } - } - // fst, fstp - if ((_pos = strstr(DisInfo.Mnem + 1, "st")) != 0) { - if (_pos[2] == 'p') - _p = True; - // op Mem - if (DisInfo.OpType[0] == otMEM) { - // fst(p) [esp] - if (DisInfo.BaseReg == 20 && !DisInfo.Offset) { - _item = Env->FStack[_TOP_]; - if (_p) - FPop(); - _ofs = _ESP_; - _sz = DisInfo.OpSize; - Env->Stack[_ofs] = _item; - _ofs += 4; - _sz -= 4; - - InitItem(&_item); - while (_sz > 0) { - Env->Stack[_ofs] = _item; - _ofs += 4; - _sz -= 4; - } - return; - } - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->FStack[_TOP_]; - if (_p) - FPop(); - - _lvarName = Env->GetLvarName(_itemSrc.IntValue, "Double"); - _line = _lvarName + " := " + _item.Value + ";"; - Env->AddToBody(_line); - _item.Value = _lvarName; - _ofs = _itemSrc.IntValue; - _sz = DisInfo.OpSize; - Env->Stack[_ofs] = _item; - _ofs += 4; - _sz -= 4; - - InitItem(&_item); - while (_sz > 0) { - Env->Stack[_ofs] = _item; - _ofs += 4; - _sz -= 4; - } - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) { - _item = Env->FStack[_TOP_]; - if (_p) - FPop(); - _line = _recN->GetName() + " := " + _item.Value + ";"; - Env->AddToBody(_line); - return; - } - } - _item = Env->FStack[_TOP_]; - if (_p) - FPop(); - - if (_itemSrc.Name != "" && !IsDefaultName(_itemSrc.Name)) - _line = _itemSrc.Name; - else - _line = _itemSrc.Value; - - _line += " := " + _item.Value + ";"; - Env->AddToBody(_line); - return; - } - // fstp - do nothing - if (DisInfo.OpType[0] == otFST) { - return; - } - } - // fcom, fcomp, fcompp - if ((_pos = strstr(DisInfo.Mnem + 1, "com")) != 0) { - if (_pos[3] == 'p') - _p = True; - if (_pos[4] == 'p') - _pp = True; - if (DisInfo.OpNum == 0) { - CmpInfo.L = FGet(0)->Value; - CmpInfo.O = CmpOp; - CmpInfo.R = FGet(1)->Value; - if (_p) { - FPop(); - // fcompp - if (_pp) - FPop(); - } - return; - } - if (DisInfo.OpNum == 1) { - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - CmpInfo.L = FGet(0)->Value; - CmpInfo.O = CmpOp; - _item = Env->Stack[_itemSrc.IntValue]; - if (_item.Value != "") - CmpInfo.R = _item.Value; - else - CmpInfo.R = Env->GetLvarName(_itemSrc.IntValue, "Double"); - if (_p) { - FPop(); - // fcompp - if (_pp) - FPop(); - } - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) { - CmpInfo.L = FGet(0)->Value; - CmpInfo.O = CmpOp; - CmpInfo.R = _recN->GetName(); - if (_p) { - FPop(); - // fcompp - if (_pp) - FPop(); - } - return; - } - } - CmpInfo.L = FGet(0)->Value; - CmpInfo.O = CmpOp; - CmpInfo.R = _itemSrc.Value; - if (_p) { - FPop(); - // fcompp - if (_pp) - FPop(); - } - return; - } - } - } - // fadd, fiadd, faddp - if ((_pos = strstr(DisInfo.Mnem + 1, "add")) != 0) { - if (_pos[3] == 'p') - _p = True; - // faddp (ST(1) = ST(0) + ST(1) and pop) - if (DisInfo.OpNum == 0) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + GetString(FGet(1), PRECEDENCE_ADD + 1); - _item.Type = "Extended"; - FSet(1, &_item); - FPop(); - return; - } - // fadd r/m (ST(0) = ST(0) + r/m) - if (DisInfo.OpNum == 1) { - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemSrc.IntValue]; - if (_item.Value != "") - _val = GetString(&_item, PRECEDENCE_ADD + 1); - else - _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) - _val = _recN->GetName(); - else - _val = GetGvarName(_itemSrc.IntValue); - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + _recN->GetName(); - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " + " + _itemSrc.Value; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - } - // fadd ST(X), ST(Y) (ST(X) = ST(X)+ST(Y)) - if (DisInfo.OpNum == 2) { - _reg1Idx = DisInfo.OpRegIdx[0] - 30; - _reg2Idx = DisInfo.OpRegIdx[1] - 30; - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_ADD) + " + " + GetString(FGet(_reg2Idx), PRECEDENCE_ADD + 1); - _item.Type = "Extended"; - FSet(_reg1Idx, &_item); - // faddp - if (_p) - FPop(); - return; - } - } - // fsub, fisub, fsubp, fsubr, fisubr, fsubrp - if ((_pos = strstr(DisInfo.Mnem + 1, "sub")) != 0) { - if (_pos[3] == 'r') { - _r = true; - if (_pos[4] == 'p') - _p = True; - } - if (_pos[3] == 'p') - _p = True; - - // fsubp, fsubrp (ST(1) = ST(1) - ST(0) and pop) - if (DisInfo.OpNum == 0) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - if (_r) - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + GetString(FGet(1), PRECEDENCE_ADD + 1); - else - _item.Value = GetString(FGet(1), PRECEDENCE_ADD) + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); - _item.Type = "Extended"; - FSet(1, &_item); - FPop(); - return; - } - // fsub r/m (ST(0) = ST(0) - r/m) - if (DisInfo.OpNum == 1) { - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemSrc.IntValue]; - if (_item.Value != "") - _val = GetString(&_item, PRECEDENCE_ADD); - else - _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - if (_r) - _item.Value = _val + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); - else - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) - _val = _recN->GetName(); - else - _val = GetGvarName(_itemSrc.IntValue); - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - if (_r) - _item.Value = _val + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); - else - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - if (_r) - _item.Value = _itemSrc.Value + " - " + GetString(FGet(0), PRECEDENCE_ADD + 1); - else - _item.Value = GetString(FGet(0), PRECEDENCE_ADD) + " - " + _itemSrc.Value; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - } - // fsub ST(X), ST(Y) (ST(X) = ST(X)-ST(Y)) - if (DisInfo.OpNum == 2) { - _reg1Idx = DisInfo.OpRegIdx[0] - 30; - _reg2Idx = DisInfo.OpRegIdx[1] - 30; - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - if (_r) - _item.Value = GetString(FGet(_reg2Idx), PRECEDENCE_ADD) + " - " + GetString(FGet(_reg1Idx), PRECEDENCE_ADD + 1); - else - _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_ADD) + " - " + GetString(FGet(_reg2Idx), PRECEDENCE_ADD + 1); - _item.Type = "Extended"; - FSet(_reg1Idx, &_item); - // fsubp - if (_p) - FPop(); - return; - } - } - // fmul, fimul, fmulp - if ((_pos = strstr(DisInfo.Mnem + 1, "mul")) != 0) { - if (_pos[3] == 'p') - _p = True; - // fmulp (ST(1) = ST(0) * ST(1) and pop) - if (DisInfo.OpNum == 0) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + GetString(FGet(1), PRECEDENCE_MULT + 1); - _item.Type = "Extended"; - FSet(1, &_item); - FPop(); - return; - } - // fmul r/m (ST(0) = r/m * ST(0)) - if (DisInfo.OpNum == 1) { - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemSrc.IntValue]; - if (_item.Value != "") - _val = GetString(&_item, PRECEDENCE_MULT + 1); - else - _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) - _val = _recN->GetName(); - else - _val = GetGvarName(_itemSrc.IntValue); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - InitItem(&_item); - _item.Precedence = PRECEDENCE_ADD; - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " * " + _itemSrc.Value; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - } - // fmul ST(X), ST(Y) (ST(X) = ST(X)*ST(Y)) - if (DisInfo.OpNum == 2) { - _reg1Idx = DisInfo.OpRegIdx[0] - 30; - _reg2Idx = DisInfo.OpRegIdx[1] - 30; - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_MULT) + " * " + GetString(FGet(_reg2Idx), PRECEDENCE_MULT + 1); - _item.Type = "Extended"; - FSet(_reg1Idx, &_item); - // fmulp - if (_p) - FPop(); - return; - } - } - // fdiv, fdivr, fidiv, fidivr, fdivp, fdivrp - if ((_pos = strstr(DisInfo.Mnem + 1, "div")) != 0) { - if (_pos[3] == 'r') { - _r = true; - if (_pos[4] == 'p') - _p = True; - } - if (_pos[3] == 'p') - _p = True; - - // fdivp (ST(1) = ST(1) / ST(0) and pop) - // fdivrp (ST(1) = ST(0) / ST(1) and pop) - if (DisInfo.OpNum == 0) { - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (_r) - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + GetString(FGet(1), PRECEDENCE_MULT + 1); - else - _item.Value = GetString(FGet(1), PRECEDENCE_MULT) + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); - _item.Type = "Extended"; - FSet(1, &_item); - FPop(); - return; - } - // fdiv r/m (ST(0) = ST(0) / r/m) - // fdivr r/m (ST(0) = r/m / ST(0)) - if (DisInfo.OpNum == 1) { - if (DisInfo.OpType[0] == otMEM) { - GetMemItem(curAdr, &_itemSrc, 0); - if (_itemSrc.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemSrc.IntValue]; - if (_item.Value != "") - _val = GetString(&_item, PRECEDENCE_MULT); - else - _val = Env->GetLvarName(_itemSrc.IntValue, "Extended"); - - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (_r) - _item.Value = _val + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); - else - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - if (_itemSrc.Flags & IF_INTVAL) { - _recN = GetInfoRec(_itemSrc.IntValue); - if (_recN && _recN->HasName()) - _val = _recN->GetName(); - else - _val = GetGvarName(_itemSrc.IntValue); - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (_r) - _item.Value = _val + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); - else - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + _val; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (_r) - _item.Value = _itemSrc.Value + " / " + GetString(FGet(0), PRECEDENCE_MULT + 1); - else - _item.Value = GetString(FGet(0), PRECEDENCE_MULT) + " / " + _itemSrc.Value; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - } - // fdiv(p) ST(X), ST(Y) (ST(X) = ST(X)/ST(Y)) - // fdivr(p) ST(X), ST(Y) (ST(X) = ST(X)/ST(Y)) - if (DisInfo.OpNum == 2) { - _reg1Idx = DisInfo.OpRegIdx[0] - 30; - _reg2Idx = DisInfo.OpRegIdx[1] - 30; - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - if (_r) - _item.Value = GetString(FGet(_reg2Idx), PRECEDENCE_MULT) + " / " + GetString(FGet(_reg1Idx), PRECEDENCE_MULT + 1); - else - _item.Value = GetString(FGet(_reg1Idx), PRECEDENCE_MULT) + " / " + GetString(FGet(_reg2Idx), PRECEDENCE_MULT + 1); - _item.Type = "Extended"; - FSet(_reg1Idx, &_item); - // fdivp - if (_p) - FPop(); - return; - } - } - // fabs - if (_dd == 'sba') { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "Abs(" + FGet(0)->Value + ")"; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - // fchs - if (_dd == 'shc') { - _item = Env->FStack[_TOP_]; - _item.Value = "-" + _item.Value; - FSet(0, &_item); - return; - } - // fld1 - if (_dd == '1dl') { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "1.0"; - _item.Type = "Extended"; - FPush(&_item); - return; - } - // fldln2 - if (_dd == 'nldl') { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "Ln(2)"; - _item.Type = "Extended"; - FPush(&_item); - return; - } - // fpatan - if (_dd == 'atap') { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - if (SameText(FGet(0)->Value, "1.0")) - _item.Value = "ArcTan(" + FGet(1)->Value + ")"; - else - _item.Value = "ArcTan(" + FGet(1)->Value + " / " + FGet(0)->Value + ")"; - _item.Type = "Extended"; - FSet(1, &_item); - FPop(); - return; - } - // fsqrt - if (_dd == 'trqs') { - InitItem(&_item); - _item.Precedence = PRECEDENCE_ATOM; - _item.Value = "Sqrt(" + FGet(0)->Value + ")"; - _item.Type = "Extended"; - FSet(0, &_item); - return; - } - // fxch - if (_dd == 'hcx') { - _reg1Idx = 1; - // fxch st(i) - if (DisInfo.OpNum == 1) { - _reg1Idx = DisInfo.OpRegIdx[0] - 30; - // fxch st(0) == fxcg - if (!_reg1Idx) - _reg1Idx = 1; - } - FXch(0, _reg1Idx); - return; - } - // fyl2x - if (_dd == 'x2ly') { - InitItem(&_item); - _item.Precedence = PRECEDENCE_MULT; - _item.Value = GetString(FGet(1), PRECEDENCE_MULT) + " * Log2(" + GetString(FGet(0), PRECEDENCE_NONE) + ")"; - _item.Type = "Extended"; - FSet(1, &_item); - FPop(); - return; - } - Env->ErrAdr = curAdr; - throw Exception("Under construction"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::AddToBody(String src) { - Body->Add(src); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompileEnv::AddToBody(TStringList* src) { - for (int n = 0; n < src->Count; n++) { - Body->Add(src->Strings[n]); - } -} - -// --------------------------------------------------------------------------- -bool __fastcall TDecompileEnv::IsExitAtBodyEnd() { - return SameText(Body->Strings[Body->Count - 1], "Exit;"); -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::GetCycleIdx(PIDXINFO IdxInfo, DISINFO* ADisInfo) { - ITEM _item; - - IdxInfo->IdxType = itUNK; - IdxInfo->IdxValue = 0; - IdxInfo->IdxStr = ADisInfo->Op1; - - if (ADisInfo->OpType[0] == otREG) { - IdxInfo->IdxType = itREG; - IdxInfo->IdxValue = ADisInfo->OpRegIdx[0]; - return; - } - if (ADisInfo->OpType[0] == otMEM) { - // Offset - if (ADisInfo->BaseReg == -1) { - IdxInfo->IdxType = itGVAR; - IdxInfo->IdxValue = ADisInfo->Offset; - IdxInfo->IdxStr = ADisInfo->Op1; - return; - } - // [ebp-N] - if (ADisInfo->BaseReg == 21) { - GetRegItem(ADisInfo->BaseReg, &_item); - IdxInfo->IdxType = itLVAR; - IdxInfo->IdxValue = _item.IntValue + ADisInfo->Offset; // LocBase - ((int)_item.Value + ADisInfo->Offset); - return; - } - // [esp-N] - if (ADisInfo->BaseReg == 20) { - IdxInfo->IdxType = itLVAR; - IdxInfo->IdxValue = _ESP_ + ADisInfo->Offset; // LocBase - (_ESP_ + ADisInfo->Offset); - return; - } - } -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompiler::GetCycleFrom() { - ITEM _item; - - if (DisInfo.OpType[1] == otIMM) - return String(DisInfo.Immediate); - if (DisInfo.OpType[1] == otREG) { - GetRegItem(DisInfo.OpRegIdx[1], &_item); - return _item.Value; - } - if (DisInfo.OpType[1] == otMEM) { - // Offset - if (DisInfo.BaseReg == -1) - return GetGvarName(DisInfo.Offset); - // [ebp-N] - if (DisInfo.BaseReg == 21) { - GetRegItem(DisInfo.BaseReg, &_item); - _item = Env->Stack[_item.IntValue + DisInfo.Offset]; - return _item.Value; - } - // [esp-N] - if (DisInfo.BaseReg == 20) { - GetRegItem(DisInfo.BaseReg, &_item); - _item = Env->Stack[_ESP_ + DisInfo.Offset]; - return _item.Value; - } - } - return "?"; -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompiler::GetCycleTo() { - ITEM _item; - - if (DisInfo.OpType[0] == otREG) { - GetRegItem(DisInfo.OpRegIdx[0], &_item); - return _item.Value; - } - if (DisInfo.OpType[0] == otMEM) { - // Offset - if (DisInfo.BaseReg == -1) - return GetGvarName(DisInfo.Offset); - // [ebp-N] - if (DisInfo.BaseReg == 21) { - GetRegItem(DisInfo.BaseReg, &_item); - _item = Env->Stack[_item.IntValue + DisInfo.Offset]; - return _item.Value; - } - // [esp-N] - if (DisInfo.BaseReg == 20) { - GetRegItem(DisInfo.BaseReg, &_item); - _item = Env->Stack[_ESP_ + DisInfo.Offset]; - return _item.Value; - } - } - return "?"; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall TDecompiler::DecompileGeneralCase(DWORD fromAdr, DWORD markAdr, PLoopInfo loopInfo, int N) { - // bool _changed = false; - int _N, _N1 = N, _N2; - DWORD _dd; - DWORD _curAdr = fromAdr, _adr, _endAdr = 0, _begAdr; - int _curPos = Adr2Pos(fromAdr); - int _len, _instrLen; - TDecompiler *de; - DISINFO _disInfo; - - while (1) { - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - // Switch at current address - if (IsFlagSet(cfSwitch, _curPos)) { - de = new TDecompiler(Env); - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - de->ClearStop(_curAdr); - try { - _adr = de->DecompileCaseEnum(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - return _endAdr; - } - // Switch at next address - if (IsFlagSet(cfSwitch, _curPos + _len)) { - _N = _disInfo.Immediate; - // add or sub - if (_dd == 'dda') - _N = -_N; - _curAdr += _len; - _curPos += _len; - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(_curAdr); // markAdr - de->ClearStop(_curAdr); - try { - _adr = de->DecompileCaseEnum(_begAdr, _N, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - return _endAdr; - } - // cmp reg, imm - if (_dd == 'pmc' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) { - _N = _disInfo.Immediate; - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bj' || _dd == 'gj' || _dd == 'egj') { - _adr = DecompileGeneralCase(_disInfo.Immediate, markAdr, loopInfo, _N1); - if (_adr > _endAdr) - _endAdr = _adr; - - _curAdr += _len; - _curPos += _len; - - _len = Disasm.Disassemble(Code + _curPos, (__int64)(_curAdr), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - Env->AddToBody(String(_N) + ":"); - _begAdr = _disInfo.Immediate; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - de->ClearStop(_begAdr); - try { - Env->AddToBody("begin"); - _adr = de->Decompile(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - - _curAdr += _len; - _curPos += _len; - } - continue; - } - } - // dec reg; sub reg, imm - if ((_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'ced' && _disInfo.OpType[0] == otREG)) { - if (_dd == 'bus') - _N2 = _disInfo.Immediate; - else - _N2 = 1; - _N1 += _N2; - if (_disInfo.OpRegIdx[0] < 8) - _N1 &= 0xFF; - else if (_disInfo.OpRegIdx[0] < 16) - _N1 &= 0xFFFF; - - _curAdr += _len; - _curPos += _len; - - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bj') { - Env->AddToBody(String(_N1 - _N2) + ".." + String(_N1 - 1) + ":"); - _begAdr = _disInfo.Immediate; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - de->ClearStop(_begAdr); - try { - Env->AddToBody("begin"); - _adr = de->Decompile(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - - _curAdr += _len; - _curPos += _len; - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - Env->AddToBody(String(_N1) + ":"); - _begAdr = _disInfo.Immediate; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - de->ClearStop(_begAdr); - try { - Env->AddToBody("begin"); - _adr = de->Decompile(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - - _curAdr += _len; - _curPos += _len; - } - continue; - } - if (_dd == 'zj' || _dd == 'ej') { - Env->AddToBody(String(_N1) + ":"); - _begAdr = _disInfo.Immediate; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - de->ClearStop(_begAdr); - try { - Env->AddToBody("begin"); - _adr = de->Decompile(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - - _curAdr += _len; - _curPos += _len; - continue; - } - if (_dd == 'znj' || _dd == 'enj') { - Env->AddToBody(String(_N1) + ":"); - _begAdr = _curAdr + _len; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - try { - Env->AddToBody("begin"); - _adr = de->Decompile(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - break; - } - } - // inc reg; add reg, imm - if ((_dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'cni' && _disInfo.OpType[0] == otREG)) { - if (_dd == 'dda') - _N2 = _disInfo.Immediate; - else - _N2 = 1; - _N1 -= _N2; - if (_disInfo.OpRegIdx[0] < 8) - _N1 &= 0xFF; - else if (_disInfo.OpRegIdx[0] < 16) - _N1 &= 0xFFFF; - - _curAdr += _len; - _curPos += _len; - - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - Env->AddToBody(String(_N1) + ":"); - _begAdr = _disInfo.Immediate; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->MarkGeneralCase(markAdr); - de->ClearStop(_begAdr); - try { - Env->AddToBody("begin"); - _adr = de->Decompile(_begAdr, 0, loopInfo); - if (_adr > _endAdr) - _endAdr = _adr; - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("GeneralCase->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - - _curAdr += _len; - _curPos += _len; - continue; - } - } - if (_dd == 'pmj') - break; - } - return _endAdr; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::MarkGeneralCase(DWORD fromAdr) { - DWORD _dd; - DWORD _curAdr = fromAdr; - int _curPos = Adr2Pos(fromAdr); - int _len, _instrLen; - DISINFO _disInfo; - - while (1) { - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - // Switch at current address - if (IsFlagSet(cfSwitch, _curPos)) { - // Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0);//ja - MarkCaseEnum(_curAdr); - return; - } - // Switch at next address - if (IsFlagSet(cfSwitch, _curPos + _len)) { - _curPos += _len; - _curAdr += _len; - // _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0);//ja - // _curPos += _len; _curAdr += _len; - MarkCaseEnum(_curAdr); - return; - } - // cmp reg, imm - if (_dd == 'pmc' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bj' || _dd == 'gj' || _dd == 'egj') { - MarkGeneralCase(_disInfo.Immediate); - - _curAdr += _len; - _curPos += _len; - - _len = Disasm.Disassemble(Code + _curPos, (__int64)(_curAdr), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - SetStop(_disInfo.Immediate); - _curAdr += _len; - _curPos += _len; - } - continue; - } - } - // sub reg, imm; dec reg - if ((_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'ced' && _disInfo.OpType[0] == otREG)) { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bus') { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - } - if (_dd == 'bj') { - SetStop(_disInfo.Immediate); - _curAdr += _len; - _curPos += _len; - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - SetStop(_disInfo.Immediate); - _curAdr += _len; - _curPos += _len; - } - continue; - } - if (_dd == 'zj' || _dd == 'ej') { - SetStop(_disInfo.Immediate); - _curAdr += _len; - _curPos += _len; - continue; - } - if (_dd == 'znj' || _dd == 'enj') - break; - } - // add reg, imm; inc reg - if ((_dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'cni' && _disInfo.OpType[0] == otREG)) { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bus') { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bj') { - SetStop(_disInfo.Immediate); - _curAdr += _len; - _curPos += _len; - continue; - } - } - if (_dd == 'zj' || _dd == 'ej') { - SetStop(_disInfo.Immediate); - _curAdr += _len; - _curPos += _len; - continue; - } - } - if (_dd == 'pmj') { - SetStop(_disInfo.Immediate); - break; - } - } -} - -// --------------------------------------------------------------------------- -int __fastcall TDecompiler::GetArrayFieldOffset(String ATypeName, int AFromOfs, int AScale, String& name, String& type) { - bool _vmt; - DWORD _vmtAdr; - int _size, _lIdx, _hIdx, _ofs, _fofs; - int _classSize = GetClassSize(GetClassAdr(ATypeName)); - int _offset = AFromOfs; - - while (1) { - if (_offset >= _classSize) - break; - _fofs = FMain_11011981->GetField(ATypeName, _offset, name, type); - if (_fofs >= 0 && GetTypeKind(type, &_size) == ikArray && GetArrayIndexes(type, 1, &_lIdx, &_hIdx)) { - _size = GetArrayElementTypeSize(type); - _ofs = AFromOfs + AScale * _lIdx; - if (_ofs >= _fofs && _ofs <= _fofs + (_hIdx - _lIdx) * _size) - return _fofs; - } - // Try next offset - _offset++; - } - return -1; -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::GetFloatItemFromStack(int Esp, PITEM Dst, int FloatType) { - BYTE _binData[16]; - float _singleVal; - double _doubleVal; - long double _extendedVal; - double _realVal; - Comp _compVal; - Currency _currVal; - ITEM _item; - - InitItem(Dst); - _item = Env->Stack[Esp]; - if (!(_item.Flags & IF_INTVAL)) { - Dst->Value = _item.Value; - Dst->Type = _item.Type; - return; - } - memset((void*)_binData, 0, 16); - memmove((void*)_binData, (void*)&_item.IntValue, 4); - if (FloatType == FT_SINGLE) { - _singleVal = 0; - memmove((void*)&_singleVal, _binData, 4); - Dst->Value = FloatToStr(_singleVal); - Dst->Type = "Single"; - return; - } - if (FloatType == FT_REAL) { - _realVal = 0; - memmove((void*)&_realVal, _binData, 4); - Dst->Value = FloatToStr(_realVal); - Dst->Type = "Real"; - return; - } - _item = Env->Stack[Esp + 4]; - memmove((void*)(_binData + 4), (void*)&_item.IntValue, 4); - if (FloatType == FT_DOUBLE) { - _doubleVal = 0; - memmove((void*)&_doubleVal, _binData, 8); - Dst->Value = FloatToStr(_doubleVal); - Dst->Type = "Double"; - return; - } - if (FloatType == FT_COMP) { - _compVal = 0; - memmove((void*)&_compVal, _binData, 8); - Dst->Value = FloatToStr(_compVal); - Dst->Type = "Comp"; - return; - } - if (FloatType == FT_CURRENCY) { - _currVal = 0; - memmove((void*)&_currVal.Val, _binData, 8); - Dst->Value = _currVal.operator String(); - Dst->Type = "Currency"; - return; - } - _item = Env->Stack[Esp + 8]; - memmove((void*)(_binData + 8), (void*)&_item.IntValue, 4); - if (FloatType == FT_EXTENDED) { - _extendedVal = 0; - memmove((void*)&_extendedVal, _binData, 10); - try { - Dst->Value = FloatToStr(_extendedVal); - Dst->Type = "Extended"; - } - catch (Exception &exception) { - throw Exception("Extended type error" + exception.Message); - } - return; - } -} - -// --------------------------------------------------------------------------- -void __fastcall TDecompiler::GetMemItem(int CurAdr, PITEM Dst, BYTE Op) { - bool _vmt; - BYTE _kind; - int _offset, _foffset, _pos, _size, _idx, _idx1, _mod, _fofs; - DWORD _adr, _vmtAdr; - PInfoRec _recN, _recN1; - ITEM _item, _itemBase, _itemIndx; - String _fname, _name, _type, _typeName, _iname, _value, _text, _lvarName; - - InitItem(Dst); - _offset = DisInfo.Offset; - if (DisInfo.BaseReg == -1) { - if (DisInfo.IndxReg == -1) { - // [Offset] - if (IsValidImageAdr(_offset)) { - Dst->Flags = IF_INTVAL; - Dst->IntValue = _offset; - return; - } - Env->ErrAdr = CurAdr; - throw Exception("Address is outside program image"); - } - // [Offset + IndxReg*Scale] - if (IsValidImageAdr(_offset)) { - _recN = GetInfoRec(_offset); - if (_recN && _recN->HasName()) - _name = _recN->GetName(); - else - _name = GetGvarName(_offset); - Dst->Value = _name + "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; - return; - } - Env->ErrAdr = CurAdr; - throw Exception("Address is outside program image"); - } - GetRegItem(DisInfo.BaseReg, &_itemBase); - // [BaseReg + Offset] - if (DisInfo.IndxReg == -1) { - // [esp+N] - if (DisInfo.BaseReg == 20) { - Dst->Flags = IF_STACK_PTR; - Dst->IntValue = _ESP_ + _offset; - _item = Env->Stack[_ESP_ + _offset]; - // Field - if (_item.Flags & IF_FIELD) { - _foffset = _item.Offset; - _offset -= _foffset; - _fname = GetRecordFields(_foffset, Env->Stack[_ESP_ + _offset].Type); - _typeName = ExtractType(_fname); - _name = Env->GetLvarName(_ESP_ + _offset, _typeName); - if (_fname.Pos(":")) { - Dst->Value = _name + "." + ExtractName(_fname); - Dst->Type = _typeName; - } - else { - Dst->Value = _name + ".f" + Val2Str0(_foffset); - } - Dst->Name = Dst->Value; - return; - } - _value = Env->GetLvarName(_ESP_ + _offset, ""); - if (_item.Value != "") - _value += "{" + _item.Value + "}"; - Dst->Value = _value; - return; - } - // lea reg, [ebp + N], bpBased - if (Op == OP_LEA && DisInfo.BaseReg == 21 && DisInfo.IndxReg == -1 && Env->BpBased) { - Dst->Flags = IF_STACK_PTR; - Dst->IntValue = _itemBase.IntValue + _offset; - return; - } - // Embedded procedures - if (Env->Embedded) { - // [ebp+8] - set flag IF_EXTERN_VAR and exit - if (DisInfo.BaseReg == 21 && _offset == 8) { - Dst->Flags = IF_EXTERN_VAR; - return; - } - if (_itemBase.Flags & IF_EXTERN_VAR) { - Dst->Value = "extlvar_" + Val2Str0(-_offset); - return; - } - } - // [reg-N] - if (_itemBase.Flags & IF_STACK_PTR) { - // xchg ecx,[ebp-XXX] - special processing - if (Op == OP_XCHG) { - Dst->Flags = IF_STACK_PTR; - Dst->IntValue = _itemBase.IntValue + _offset; - Dst->Value = _itemBase.Value; - Dst->Name = _itemBase.Name; - return; - } - if (_itemBase.Flags & IF_ARG) { - Dst->Flags = IF_STACK_PTR; - Dst->IntValue = _itemBase.IntValue + _offset; - Dst->Value = _itemBase.Value; - Dst->Name = _itemBase.Name; - return; - } - if (_itemBase.Flags & IF_ARRAY_PTR) { - Dst->Flags = IF_STACK_PTR; - Dst->IntValue = _itemBase.IntValue + _offset; - if (_itemBase.Value != "") - Dst->Value = _itemBase.Value + "[]"; - if (_itemBase.Name != "") - Dst->Name = _itemBase.Name + "[]"; - return; - } - _item = Env->Stack[_itemBase.IntValue + _offset]; - // Arg - if (_item.Flags & IF_ARG) { - // Dst->Flags = IF_STACK_PTR; - // Dst->IntValue = _itemBase.IntValue + _offset; - AssignItem(Dst, &_item); - // Dst->Flags &= ~IF_ARG; - // Dst->Value = _item.Name; - // Dst->Name = _item.Name; - return; - } - // Var - if (_item.Flags & IF_VAR) { - _item.Flags &= ~IF_VAR; - _item.Type = "^" + _item.Type; - AssignItem(Dst, &_item); - Dst->Name = Env->GetLvarName(_itemBase.IntValue + _offset, ""); - return; - } - // Field - if (_item.Flags & IF_FIELD) { - _foffset = _item.Offset; - _offset -= _foffset; - _fname = GetRecordFields(_foffset, Env->Stack[_itemBase.IntValue + _offset].Type); - _typeName = ExtractType(_fname); - _name = Env->GetLvarName(_itemBase.IntValue + _offset, _typeName); - if (_fname.Pos(":")) { - Dst->Value = _name + "." + ExtractName(_fname); - Dst->Type = _typeName; - } - else { - Dst->Value = _name + ".f" + Val2Str0(_foffset); - } - Dst->Name = _name; - return; - } - // Not interface - if (_item.Type == "" || GetTypeKind(_item.Type, &_size) != ikInterface) { - _lvarName = Env->GetLvarName(_itemBase.IntValue + _offset, ""); - Env->Stack[_itemBase.IntValue + _offset].Name = _lvarName; - Dst->Flags = IF_STACK_PTR; - Dst->IntValue = _itemBase.IntValue + _offset; - Dst->Value = _lvarName; - Dst->Name = Dst->Value; - return; - } - } - // [BaseReg] - if (!_offset) { - _typeName = _itemBase.Type; - if (_itemBase.Flags & IF_VAR) { - AssignItem(Dst, &_itemBase); - Dst->Flags &= ~IF_VAR; - Dst->Name = ""; - return; - } - if (_itemBase.Flags & IF_RECORD_FOFS) { - _value = _itemBase.Value; - if (_itemBase.Flags & IF_ARRAY_PTR) - _value += "[]"; - _text = GetRecordFields(_itemBase.Offset, _itemBase.Type); - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_itemBase.Offset); - _typeName = _text; - } - Dst->Value = _value; - Dst->Type = _typeName; - Dst->Name = ""; - return; - } - if (_itemBase.Flags & IF_ARRAY_PTR) { - Dst->Value = _itemBase.Value + "[]"; - Dst->Type = GetArrayElementType(_typeName); - Dst->Name = ""; - return; - } - if (_itemBase.Flags & IF_STACK_PTR) { - _item = Env->Stack[_itemBase.IntValue]; - AssignItem(Dst, &_item); - return; - } - if (_itemBase.Flags & IF_INTVAL) { - _adr = _itemBase.IntValue; - if (IsValidImageAdr(_adr)) { - _recN = GetInfoRec(_adr); - if (_recN) { - Dst->Value = _recN->GetName(); - Dst->Type = _recN->type; - return; - } - } - } - if (_typeName == "") { - _typeName = "Pointer"; - // _name = GetDecompilerRegisterName(DisInfo.BaseReg); - // _typeName = ManualInput(CurProcAdr, CurAdr, "Define type of base register (" + _name + ")", "Type:"); - // if (_typeName == "") - // { - // Env->ErrAdr = CurAdr; - // throw Exception("Bye!"); - // } - } - if (_typeName[1] == '^') // Pointer to var - { - _value = _itemBase.Value; - _typeName = GetTypeDeref(_typeName); - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _text = GetRecordFields(0, _typeName); - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f0"; - _typeName = _text; - } - } - if (_kind == ikArray) { - _value += "[ofs=" + String(_offset) + "]"; - } - Dst->Value = _value; - Dst->Name = GetDecompilerRegisterName(DisInfo.BaseReg); - Dst->Type = _typeName; - return; - } - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikEnumeration) { - Dst->Value = GetEnumerationString(_typeName, _itemBase.Value); - Dst->Type = _typeName; - return; - } - if (_kind == ikLString || _kind == ikString) { - Dst->Value = _itemBase.Value + "[1]"; - Dst->Type = "Char"; - return; - } - if (_kind == ikRecord) { - _text = GetRecordFields(_offset, _typeName); - if (_text.Pos(":")) { - _value = _itemBase.Value + "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value = _itemBase.Value + ".f" + Val2Str0(_offset); - _typeName = _text; - } - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - - Dst->Flags = IF_VMT_ADR; - if (_itemBase.Flags & IF_INTERFACE) { - Dst->Flags |= IF_INTERFACE; - Dst->Value = _itemBase.Value; - } - Dst->IntValue = GetClassAdr(_typeName); - Dst->Type = _typeName; - return; - } - // [BaseReg+Offset] - if (IsValidImageAdr(_offset)) { - _recN = GetInfoRec(_offset); - if (_recN && _recN->HasName()) - _name = _recN->GetName(); - else - _name = GetGvarName(_offset); - Dst->Value = _name + "[" + GetDecompilerRegisterName(DisInfo.BaseReg) + "]"; - return; - } - if (_itemBase.Flags & IF_RECORD_FOFS) { - _value = _itemBase.Value; - if (_itemBase.Flags & IF_ARRAY_PTR) - _value += "[]"; - _text = GetRecordFields(_itemBase.Offset + _offset, _itemBase.Type); - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_itemBase.Offset + _offset); - _typeName = _text; - } - Dst->Value = _value; - Dst->Type = _typeName; - Dst->Name = ""; - return; - } - if (_itemBase.Flags & IF_ARRAY_PTR) { - if ((_itemBase.Flags & IF_STACK_PTR) && Env->Stack[_itemBase.IntValue].Value != "") - Dst->Value = Env->Stack[_itemBase.IntValue].Value + "["; - else - Dst->Value = GetDecompilerRegisterName(DisInfo.BaseReg) + "["; - if (_offset > 0) - Dst->Value += " + " + String(_offset); - else if (_offset < 0) - Dst->Value += " - " + String(-_offset); - Dst->Value += "]"; - return; - } - _typeName = _itemBase.Type; - if (_typeName == "") { - _typeName = "Pointer"; - // _name = GetDecompilerRegisterName(DisInfo.BaseReg); - // _typeName = ManualInput(CurProcAdr, CurAdr, "Define type of base register (" + _name + ")", "Type:"); - // if (_typeName == "") - // { - // Env->ErrAdr = CurAdr; - // throw Exception("Bye!"); - // } - } - if (_typeName[1] == '^') - _typeName = GetTypeDeref(_typeName); - - _itemBase.Flags = 0; - if (_itemBase.Value == "") - _itemBase.Value = GetDecompilerRegisterName(DisInfo.BaseReg); - _itemBase.Type = _typeName; - SetRegItem(DisInfo.BaseReg, &_itemBase); - - _iname = _itemBase.Value; - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikLString || _kind == ikString) { - _value = _iname + "[" + String(_offset + 1) + "]"; - _typeName = "Char"; - } - else if (_kind == ikRecord) { - if (_itemBase.Value != "") - _value = _itemBase.Value; - else - _value = GetDecompilerRegisterName(DisInfo.BaseReg); - if (Op == OP_LEA) // address of field with ofs=_offset in structure _typeName - { - Dst->Flags = IF_RECORD_FOFS; - Dst->Value = _value; - Dst->Type = _typeName; - Dst->Offset = _offset; - return; - } - _text = GetRecordFields(_offset, _typeName); - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_offset); - _typeName = _text; - } - } - else if (_kind == ikArray) { - _value = _iname + "[ofs=" + String(_offset) + "]"; - } - else if (_kind == ikDynArray) { - _typeName = GetArrayElementType(_typeName); - if (_typeName == "") { - Env->ErrAdr = CurAdr; - throw Exception("Type of array elements not found"); - } - if (GetTypeKind(_typeName, &_size) == ikRecord) { - int _k = 0; - _size = GetRecordSize(_typeName); - if (_offset < 0) { - while (1) { - _offset += _size; - _k--; - if (_offset >= 0 && _offset < _size) - break; - } - } - if (_offset >= _size) { - while (1) { - _offset -= _size; - _k++; - if (_offset >= 0 && _offset < _size) - break; - } - } - _text = GetRecordFields(_offset, _typeName); - if (_text == "") { - _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset), "[Name]:Type:"); - if (_text == "") { - Env->ErrAdr = CurAdr; - throw Exception("Bye!"); - } - } - _value = _itemBase.Value + "[" + String(_k) + "]"; - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_offset); - _typeName = _text; - } - } - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - else if (_kind == ikVMT || _kind == ikClass) { - _fofs = FMain_11011981->GetField(_typeName, _offset, _name, _type); - if (_fofs < 0) { - _text = ManualInput(CurProcAdr, CurAdr, "Define correct type of field " + _typeName + ".f" + Val2Str0(_offset), "Type:"); - if (_text == "") { - Env->ErrAdr = CurAdr; - throw Exception("Bye!"); - } - _recN1 = GetInfoRec(_vmtAdr); - _recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, _offset, -1, "", _text); - - _fofs = FMain_11011981->GetField(_typeName, _offset, _name, _type); - if (_fofs < 0) { - Env->ErrAdr = CurAdr; - throw Exception("Field f" + Val2Str0(_offset) + " not found"); - } - } - _value = _name; - _typeName = _type; - _foffset = _fofs; - - // if (Op != OP_LEA) - // { - _kind = GetTypeKind(_typeName, &_size); - // Interface - if (_kind == ikInterface) { - _typeName[1] = 'T'; - Dst->Flags = IF_INTERFACE; - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - // Record - if (_kind == ikRecord) { - _text = GetRecordFields(_offset - _foffset, _typeName); - if (_text == "") { - _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset - _fofs), "[Name]:Type:"); - if (_text == "") { - Env->ErrAdr = CurAdr; - throw Exception("Bye!"); - } - } - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_offset); - _typeName = _text; - } - } - // Array - if (_kind == ikArray) { - _value += "[ofs=" + String(_offset - _foffset) + "]"; - } - if (!SameText(_iname, "Self")) - _value = _iname + "." + _value; - // } - } - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - // [BaseReg + IndxReg*Scale + Offset] - else { - GetRegItem(DisInfo.IndxReg, &_itemIndx); - if (Op == OP_LEA) { - if (_itemBase.Flags & IF_STACK_PTR) - Dst->Flags |= IF_STACK_PTR; - Dst->Value = GetDecompilerRegisterName(DisInfo.BaseReg) + " + " + GetDecompilerRegisterName(DisInfo.IndxReg) + " * " + String(DisInfo.Scale); - if (_offset > 0) - Dst->Value += String(_offset); - else if (_offset < 0) - Dst->Value += String(-_offset); - return; - } - _typeName = _itemBase.Type; - if (_typeName == "") { - // esp - if (DisInfo.BaseReg == 20) { - Dst->Value = Env->GetLvarName(_ESP_ + _offset + DisInfo.Scale, "") + "[" + _itemIndx.Value + "]"; - return; - } - // ebp - if (DisInfo.BaseReg == 21 && (_itemBase.Flags & IF_STACK_PTR)) { - Dst->Value = Env->GetLvarName(_itemBase.IntValue + _offset + DisInfo.Scale, "") + "[" + _itemIndx.Value + "]"; - return; - } - _kind = 0; - // Lets try analyze _itemBase if it is address - if (_itemBase.Flags & IF_INTVAL) { - _adr = _itemBase.IntValue; - if (IsValidImageAdr(_adr)) { - _recN = GetInfoRec(_adr); - if (_recN) { - _kind = _recN->kind; - if (_recN->type != "" && (_kind == ikUnknown || _kind == ikData)) - _kind = GetTypeKind(_recN->type, &_size); - } - } - } - while (_kind == 0 || _kind == ikData) { - _text = "Pointer"; - // _text = ManualInput(CurProcAdr, CurAdr, "Define type of base register", "Type:"); - // if (_text == "") - // { - // Env->ErrAdr = CurAdr; - // throw Exception("Bye!"); - // } - _typeName = _text; - _kind = GetTypeKind(_typeName, &_size); - } - } - else { - if (_typeName[1] == '^') - _typeName = GetTypeDeref(_typeName); - - _kind = GetTypeKind(_typeName, &_size); - while (!_kind) { - _text = "Pointer"; - // _text = ManualInput(CurProcAdr, CurAdr, "Define type of base register", "Type:"); - // if (_text == "") - // { - // Env->ErrAdr = CurAdr; - // throw Exception("Bye!"); - // } - _typeName = _text; - _kind = GetTypeKind(_typeName, &_size); - } - } - if (_kind == ikClass || _kind == ikVMT) { - _fofs = GetArrayFieldOffset(_typeName, _offset, DisInfo.Scale, _name, _type); - while (_fofs < 0) { - _text = ManualInput(CurProcAdr, CurAdr, "Define actual offset (in hex) of array field", "Offset:"); - if (_text == "") { - Env->ErrAdr = CurAdr; - throw Exception("Bye!"); - } - sscanf(AnsiString(_text).c_str(), "%lX", &_offset); - _fofs = GetArrayFieldOffset(_typeName, _offset, DisInfo.Scale, _name, _type); - } - if (!SameText(_itemBase.Value, "Self")) - _value = _itemBase.Value + "."; - if (_name != "") - _value += _name; - else - _value += "f" + Val2Str0(_fofs); - _value += "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; - - Dst->Value = _value; - Dst->Type = GetArrayElementType(_type); - return; - } - if (_kind == ikLString || _kind == ikCString || _kind == ikPointer) { - Dst->Value = GetDecompilerRegisterName(DisInfo.BaseReg) + "[" + GetDecompilerRegisterName(DisInfo.IndxReg); - if (_kind == ikLString) - _offset++; - if (_offset > 0) - Dst->Value += " + " + String(_offset); - else if (_offset < 0) - Dst->Value += " - " + String(-_offset); - Dst->Value += "]"; - Dst->Type = "Char"; - return; - } - if (_kind == ikRecord) { - _value = _itemBase.Value; - _text = GetRecordFields(_offset + DisInfo.Scale, _typeName); - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_offset); - _typeName = _text; - } - if (GetTypeKind(_typeName, &_size) == ikArray) { - _value += "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; - _typeName = GetArrayElementType(_typeName); - } - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - if (_kind == ikArray) { - if (_itemBase.Flags & IF_INTVAL) { - _adr = _itemBase.IntValue; - _recN = GetInfoRec(_adr); - if (_recN && _recN->HasName()) - _name = _recN->GetName(); - else - _name = GetGvarName(_adr); - } - _name = _itemBase.Value; - _typeName = GetArrayElementType(_typeName); - if (_typeName == "") { - Env->ErrAdr = CurAdr; - throw Exception("Type of array elements not found"); - } - if (GetTypeKind(_typeName, &_size) == ikRecord) { - int _k = 0; - _size = GetRecordSize(_typeName); - if (_offset < 0) { - while (1) { - _offset += _size; - _k--; - if (_offset >= 0 && _offset < _size) - break; - } - } - if (_offset > _size) { - while (1) { - _offset -= _size; - _k++; - if (_offset >= 0 && _offset < _size) - break; - } - } - _text = GetRecordFields(_offset, _typeName); - if (_text == "") { - _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset), "[Name]:Type:"); - if (_text == "") { - Env->ErrAdr = CurAdr; - throw Exception("Bye!"); - } - } - _value = _name + "["; - if (_itemIndx.Value != "") - _value += _itemIndx.Value; - else - _value += GetDecompilerRegisterName(DisInfo.IndxReg); - if (_k < 0) - _value += " - " + String(-_k) + "]"; - else if (_k > 0) - _value += " + " + String(_k) + "]"; - else - _value += "]"; - - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_offset); - _typeName = _text; - } - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - - if (!GetArrayIndexes(_itemBase.Type, 1, &_idx, &_idx1)) { - Env->ErrAdr = CurAdr; - throw Exception("Incorrect array definition"); - } - _mod = _offset % DisInfo.Scale; - if (_mod) { - Env->ErrAdr = CurAdr; - throw Exception("Array element is record"); - } - - if (_itemIndx.Value != "") - _value = _itemBase.Value + "[" + _itemIndx.Value + "]"; - else - _value = _itemBase.Value + "[" + GetDecompilerRegisterName(DisInfo.IndxReg) + "]"; - Dst->Value = _value; - Dst->Type = GetArrayElementType(_itemBase.Type); - return; - } - if (_kind == ikDynArray) { - _typeName = GetArrayElementType(_typeName); - if (_typeName == "") { - Env->ErrAdr = CurAdr; - throw Exception("Type of array elements not found"); - } - _value = _itemBase.Value + "["; - if (_itemIndx.Value != "") - _value += _itemIndx.Value; - else - _value += GetDecompilerRegisterName(DisInfo.IndxReg); - _value += "]"; - - if (GetTypeKind(_typeName, &_size) == ikRecord) { - int _k = 0; - _size = GetRecordSize(_typeName); - if (_offset < 0) { - while (1) { - _offset += _size; - _k--; - if (_offset >= 0 && _offset < _size) - break; - } - } - if (_offset > _size) { - while (1) { - _offset -= _size; - _k++; - if (_offset >= 0 && _offset < _size) - break; - } - } - _text = GetRecordFields(_offset, _typeName); - if (_text == "") { - _text = ManualInput(CurProcAdr, CurAdr, "Define [name:]type of field " + _typeName + ".f" + Val2Str0(_offset), "[Name]:Type:"); - if (_text == "") { - Env->ErrAdr = CurAdr; - throw Exception("Bye!"); - } - } - _value = _itemBase.Value + "["; - if (_itemIndx.Value != "") - _value += _itemIndx.Value; - else - _value += GetDecompilerRegisterName(DisInfo.IndxReg); - if (_k < 0) - _value += " - " + String(-_k) + "]"; - else if (_k > 0) - _value += " + " + String(_k) + "]"; - else - _value += "]"; - - if (_text.Pos(":")) { - _value += "." + ExtractName(_text); - _typeName = ExtractType(_text); - } - else { - _value += ".f" + Val2Str0(_offset); - _typeName = _text; - } - } - Dst->Value = _value; - Dst->Type = _typeName; - return; - } - Env->ErrAdr = CurAdr; - throw Exception("Under construction"); - } -} - -// --------------------------------------------------------------------------- -String __fastcall TDecompiler::GetStringArgument(PITEM item) { - int _idx, _ap, _len, _size; - DWORD _adr; - PInfoRec _recN; - String _key; - - if (item->Name != "") - return item->Name; - - if (item->Flags & IF_STACK_PTR) { - Env->Stack[item->IntValue].Type = "String"; - return Env->GetLvarName(item->IntValue, "String"); - } - else if (item->Flags & IF_INTVAL) { - _adr = item->IntValue; - if (_adr == 0) { - return ""; - } - else if (IsValidImageAdr(_adr)) { - _ap = Adr2Pos(_adr); - if (_ap >= 0) { - _recN = GetInfoRec(_adr); - if (_recN && (_recN->kind == ikLString || _recN->kind == ikWString || _recN->kind == ikUString)) - return _recN->GetName(); - - _len = wcslen((wchar_t*)(Code + _ap)); - WideString wStr = WideString((wchar_t*)(Code + _ap)); - _size = WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), -1, 0, 0, 0, 0); - if (_size) { - char* tmpBuf = new char[_size + 1]; - WideCharToMultiByte(CP_ACP, 0, wStr.c_bstr(), -1, (LPSTR)tmpBuf, _size, 0, 0); - String str = TransformString(tmpBuf, _size); - delete[]tmpBuf; - return str; - } - } - else { - _key = Val2Str8(_adr); - _idx = BSSInfos->IndexOf(_key); - if (_idx != -1) - _recN = (PInfoRec)BSSInfos->Objects[_idx]; - if (_recN) - return _recN->GetName(); - else - return item->Value; - } - } - else { - return item->Value; - } - } - else { - return item->Value; - } -} - -// --------------------------------------------------------------------------- -int __fastcall TDecompiler::AnalyzeConditions(int brType, DWORD curAdr, DWORD sAdr, DWORD jAdr, PLoopInfo loopInfo) { - DWORD _curAdr = curAdr; - DWORD _begAdr, _bodyBegAdr, _bodyEndAdr, _jmpAdr = jAdr; - TDecompiler *de; - String _line; - - // simple if - if (brType == 0) { - if (CmpInfo.O == 'R') // not in - _line = "if (not (" + CmpInfo.L + " in " + CmpInfo.R + ")) then"; - else - _line = "if (" + CmpInfo.L + " " + GetInvertCondition(CmpInfo.O) + " " + CmpInfo.R + ") then"; - Env->AddToBody(_line); - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(CmpAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_begAdr, 0, loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("If->" + exception.Message); - } - Env->RestoreContext(_begAdr); // if (de->WasRet) - delete de; - } - // complex if - else if (brType == 1) { - _bodyBegAdr = _curAdr; - if (!Env->GetBJLRange(sAdr, &_bodyBegAdr, &_bodyEndAdr, &_jmpAdr, loopInfo)) { - Env->ErrAdr = _curAdr; - throw Exception("Control flow under construction"); - } - Env->CmpStack->Clear(); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(_bodyBegAdr); - try { - de->Decompile(sAdr, CF_BJL, loopInfo); - } - catch (Exception &exception) { - delete de; - throw Exception("Complex if->" + exception.Message); - } - delete de; - - if (_bodyEndAdr > _bodyBegAdr) { - Env->CreateBJLSequence(sAdr, _bodyBegAdr, _bodyEndAdr); - Env->BJLAnalyze(); - - _line = "if " + Env->PrintBJL() + " then"; - Env->AddToBody(_line); - Env->SaveContext(_bodyBegAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(_bodyEndAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_bodyBegAdr, 0, loopInfo); - if (_jmpAdr && IsExit(_jmpAdr)) { - Env->AddToBody("Exit;"); - } - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("Complex if->" + exception.Message); - } - Env->RestoreContext(_bodyBegAdr); // if (_jmpAdr || de->WasRet) - delete de; - - if (_jmpAdr) { - if (!IsExit(_jmpAdr)) { - Env->AddToBody("else"); - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(_jmpAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_begAdr, CF_ELSE, loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("IfElse->" + exception.Message); - } - Env->RestoreContext(_begAdr); // if (de->WasRet) - delete de; - } - } - } - else { - Env->CreateBJLSequence(sAdr, _bodyBegAdr, _bodyEndAdr); - Env->BJLAnalyze(); - - _line = "if " + Env->PrintBJL() + " then"; - } - } - // cycle - else if (brType == 2) { - if (CmpInfo.O == 'R') // not in - _line = "if (not (" + CmpInfo.L + " in " + CmpInfo.R + ")) then"; - else - _line = "if (" + CmpInfo.L + " " + GetInvertCondition(CmpInfo.O) + " " + CmpInfo.R + ") then"; - Env->AddToBody(_line); - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(CmpAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_begAdr, 0, loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("If->" + exception.Message); - } - Env->RestoreContext(_begAdr); // if (de->WasRet) - delete de; - } - // simple if else - else if (brType == 3) { - if (CmpInfo.O == 'R') // not in - _line = "if (not (" + CmpInfo.L + " in " + CmpInfo.R + ")) then"; - else - _line = "if (" + CmpInfo.L + " " + GetInvertCondition(CmpInfo.O) + " " + CmpInfo.R + ") then"; - Env->AddToBody(_line); - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(CmpAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_begAdr, 0, loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("IfElse->" + exception.Message); - } - Env->RestoreContext(_begAdr); - delete de; - - Env->AddToBody("else"); - _begAdr = _curAdr; - Env->SaveContext(_begAdr); - de = new TDecompiler(Env); - de->SetStackPointers(this); - de->SetDeFlags(DeFlags); - de->SetStop(_jmpAdr); - try { - Env->AddToBody("begin"); - _curAdr = de->Decompile(_begAdr, CF_ELSE, loopInfo); - Env->AddToBody("end"); - } - catch (Exception &exception) { - delete de; - throw Exception("IfElse->" + exception.Message); - } - Env->RestoreContext(_begAdr); // if (de->WasRet) - delete de; - } - else { - _line = "if (" + CmpInfo.L + " " + GetDirectCondition(CmpInfo.O) + " " + CmpInfo.R + ") then Break;"; - Env->AddToBody(_line); - } - return _curAdr; -} -// --------------------------------------------------------------------------- -// cfLoc - make XRefs -// Names -// --------------------------------------------------------------------------- -// hints -// DynArrayClear == (varName := Nil); -// DynArraySetLength == SetLength(varName, colsnum, rowsnum) -// @Assign == AssignFile -// @Close == CloseFile -// @Flush == Flush -// @ResetFile;@ResetText == Reset -// @RewritFile4@RewritText == Rewrite -// @Str2Ext == Str(val:width:prec,s) -// @Write0LString == Write -// @WriteLn == WriteLn -// @LStrPos == Pos -// @LStrCopy == Copy -// @LStrLen == Length -// @LStrDelete == Delete -// @LStrInsert == Insert -// @LStrCmp == '=' -// @UStrCmp == '=' -// @RandInt == Random -// @LStrOfChar == StringOfChar -// 0x61 = Ord('a') -// @LStrFromChar=Chr -// @LStrToPChar=PChar -// @LStrFromArray=String(src,len) -// --------------------------------------------------------------------------- -// Constructions -// --------------------------------------------------------------------------- -// Length -// test reg, reg -// jz @1 -// mov reg, [reg-4] -// or -// sub reg, 4 -// mov reg, [reg] -// --------------------------------------------------------------------------- -// mod 2 -// and eax, 80000001 -// jns @1 -// dec eax -// or eax, 0fffffffe -// inc eax -// @1 -// --------------------------------------------------------------------------- -// mod 2^k -// and eax, (80000000 | (2^k - 1)) -// jns @1 -// dec eax -// or eax, -2^k -// inc eax -// @1 -// --------------------------------------------------------------------------- -// div 2^k -// test reg, reg -// jns @1 -// add reg, (2^k - 1) -// sar reg, k -// @1 -// --------------------------------------------------------------------------- -// mod N -// mov reg, N (reg != eax) -// cdq -// idiv reg -// use edx -// --------------------------------------------------------------------------- -// in [0..N] -// sub eax, (N + 1) -// jb @body -// --------------------------------------------------------------------------- -// in [N1..N2,M1..M2] -// add eax, -N1 -// sub eax, (N2 - N1 + 1) -// jb @body -// add eax, -(M1 - N2 - 1) -// sub eax, (M1 - M2 + 1) -// jnb @end -// @body -// ... -// @end -// --------------------------------------------------------------------------- -// not in [N1..N2,M1..M2] -// add eax, -N1 -// sub eax, (N2 - N1 + 1) -// jb @end -// add eax, -(M1 - N2 - 1) -// sub eax, (M1 - M2 + 1) -// jb @end -// @body -// ... -// @end -// --------------------------------------------------------------------------- -// Int64 comparison if (A > B) then >(jbe,jle) >=(jb,jl) <(jae,jge) <=(ja,jg) -// cmp highA,highB -// jnz(jne) @1 -// {pop reg} -// {pop reg} -// cmp lowA,lowB -// jbe @2 (setnbe) -// jmp @3 -// @1: -// {pop reg} -// {pop reg} -// jle @2 (setnle) -// @3 -// body -// @2 -// --------------------------------------------------------------------------- -// LStrAddRef - if exists, then no prefix const -// --------------------------------------------------------------------------- -// Exit in except block -// @DoneExcept -// jmp ret -// @DoneExcept -// --------------------------------------------------------------------------- -// If array of strings before procedure (function), then this array is declared -// in var section -// --------------------------------------------------------------------------- -// mov [A],0 -// mov [A + 4], 0x3FF00000 -// ->(Double)A := (00 00 00 00 00 00 F0 3F) Bytes in revers order! -// --------------------------------------------------------------------------- -// exetended -> tools -// push A -// push B -// push C -// C,B,A in reverse order -// --------------------------------------------------------------------------- -// @IsClass<-> (eax is edx) -// --------------------------------------------------------------------------- -// SE4(5D1817) - while!!! diff --git a/Sources/Libs/Decompiler.h b/Sources/Libs/Decompiler.h deleted file mode 100644 index 22be78e..0000000 --- a/Sources/Libs/Decompiler.h +++ /dev/null @@ -1,305 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef DecompilerH -#define DecompilerH - -#include "Main.h" -// --------------------------------------------------------------------------- -// Precedence of operations -#define PRECEDENCE_ATOM 8 -#define PRECEDENCE_NOT 4 //@,not -#define PRECEDENCE_MULT 3 //*,/,div, mod,and,shl,shr,as -#define PRECEDENCE_ADD 2 //+,-,or,xor -#define PRECEDENCE_CMP 1 //=,<>,<,>,<=,>=,in,is -#define PRECEDENCE_NONE 0 - -#define TAB_SIZE 2 - -#define IF_ARG 1 -#define IF_VAR 2 -#define IF_STACK_PTR 4 -#define IF_CALL_RESULT 8 -#define IF_VMT_ADR 16 -#define IF_CYCLE_VAR 32 -#define IF_FIELD 64 -#define IF_ARRAY_PTR 128 -#define IF_INTVAL 256 -#define IF_INTERFACE 512 -#define IF_EXTERN_VAR 1024 //User for embedded procedures -#define IF_RECORD_FOFS 2048 //Offset inside record - -#define CF_CONSTRUCTOR 1 -#define CF_DESTRUCTOR 2 -#define CF_FINALLY 4 -#define CF_EXCEPT 8 -#define CF_LOOP 16 -#define CF_BJL 32 -#define CF_ELSE 64 - -#define CMP_FAILED 0 -#define CMP_BRANCH 1 -#define CMP_SET 2 - -// BJL -#define MAXSEQNUM 1024 - -#define BJL_USED -1 -#define BJL_EMPTY 0 -#define BJL_BRANCH 1 -#define BJL_JUMP 2 -#define BJL_LOC 3 -#define BJL_SKIP_BRANCH 4 //branches for IntOver, BoundErr,... - -typedef struct { - char state; // 'U' not defined; 'B' branch; 'J' jump; '@' label; 'R' return; 'S' switch - int bcnt; // branches to... count - DWORD address; - String dExpr; // condition of direct expression - String iExpr; // condition of inverse expression - String result; -} TBJLInfo; - -typedef struct { - bool branch; - bool loc; - int type; - int address; - int idx; // IDX in BJLseq -} TBJL; -// BJL - -typedef struct { - String L; - char O; - String R; -} CMPITEM, *PCMPITEM; - -typedef struct { - BYTE Precedence; - int Size; // Size in bytes - int Offset; // Offset from beginning of type - DWORD IntValue; // For array element size calculation - DWORD Flags; - String Value; - String Value1; // For various purposes - String Type; - String Name; -} ITEM, *PITEM; - -typedef struct { - String Value; - String Name; -} WHAT, *PWHAT; - -#define itUNK 0 -#define itREG 1 -#define itLVAR 2 -#define itGVAR 3 - -typedef struct { - BYTE IdxType; - int IdxValue; - String IdxStr; -} IDXINFO, *PIDXINFO; - -class TForInfo { -public: - bool NoVar; - bool Down; // downto (=true) - int StopAdr; // instructions are ignored from this address and to end of cycle - String From; - String To; - IDXINFO VarInfo; - IDXINFO CntInfo; - - __fastcall TForInfo(bool ANoVar, bool ADown, int AStopAdr, String AFrom, String ATo, BYTE AVarType, int AVarIdx, BYTE ACntType, int ACntIdx); -}; - -typedef TForInfo *PForInfo; - -class TWhileInfo { -public: - bool NoCondition; // No condition - - __fastcall TWhileInfo(bool ANoCond); -}; - -typedef TWhileInfo *PWhileInfo; - -class TLoopInfo { -public: - BYTE Kind; // 'F'- for; 'W' - while; 'T' - while true; 'R' - repeat - DWORD ContAdr; // Continue address - DWORD BreakAdr; // Break address - DWORD LastAdr; // Last address for decompilation (skip some last instructions) - PForInfo forInfo; - PWhileInfo whileInfo; - - __fastcall TLoopInfo(BYTE AKind, DWORD AContAdr, DWORD ABreakAdr, DWORD ALastAdr); - __fastcall ~TLoopInfo(); -}; - -typedef TLoopInfo *PLoopInfo; - -// cmpStack Format: "XYYYYYYY^ZZZZ" (== YYYYYY X ZZZZ) -// 'A'-JO;'B'-JNO;'C'-JB;'D'-'JNB';'E'-JZ;'F'-JNZ;'G'-JBE;'H'-JA; -// 'I'-'JS';'J'-JNS;'K'-JP;'L'-JNP;'M'-JL;'N'-JGE;'O'-JLE;'P'-JG - -// Only registers eax, ecx, edx, ebx, esp, ebp, esi, edi -typedef ITEM REGS[8]; - -class TNamer { -public: - int MaxIdx; - TStringList *Names; - - __fastcall TNamer(); - __fastcall ~TNamer(); - String __fastcall MakeName(String shablon); -}; - -struct TCaseTreeNode; - -struct TCaseTreeNode { - TCaseTreeNode *LNode; - TCaseTreeNode *RNode; - DWORD ZProc; - int FromVal; - int ToVal; -}; - -// structure for saving context of all registers -typedef struct { - DWORD adr; - REGS gregs; // general registers - REGS fregs; // float point registers -} DCONTEXT, *PDCONTEXT; - -class TDecompiler; - -class TDecompileEnv { -public: - String ProcName; // Name of decompiled procedure - DWORD StartAdr; // Start of decompilation area - int Size; // Size of decompilation area - int Indent; // For output source code - bool Alarm; - bool BpBased; - int LocBase; - DWORD StackSize; - PITEM Stack; - DWORD ErrAdr; - String LastResString; - TStringList *Body; - ITEM RegInfo[8]; - ITEM FStack[8]; // Floating registers stack - TNamer *Namer; - int BJLnum; - int BJLmaxbcnt; - TList *SavedContext; - TList *BJLseq; // TBJLInfo - TList *bjllist; // TBJL - TList *CmpStack; - bool Embedded; // Is proc embedded - TStringList *EmbeddedList; // List of embedded procedures addresses - - __fastcall TDecompileEnv(DWORD AStartAdr, int ASize, PInfoRec recN); - __fastcall ~TDecompileEnv(); - String __fastcall GetFieldName(PFIELDINFO fInfo); - String __fastcall GetArgName(PARGINFO argInfo); - String __fastcall GetGvarName(DWORD adr); - String __fastcall GetLvarName(int Ofs, String Type); - void __fastcall AssignItem(PITEM DstItem, PITEM SrcItem); - void __fastcall AddToBody(String src); - void __fastcall AddToBody(TStringList* src); - bool __fastcall IsExitAtBodyEnd(); - - void __fastcall OutputSourceCodeLine(String line); - void __fastcall OutputSourceCode(); - void __fastcall MakePrototype(); - void __fastcall DecompileProc(); - // BJL - bool __fastcall GetBJLRange(DWORD fromAdr, DWORD* bodyBegAdr, DWORD* bodyEndAdr, DWORD* jmpAdr, PLoopInfo loopInfo); - void __fastcall CreateBJLSequence(DWORD fromAdr, DWORD bodyBegAdr, DWORD bodyEndAdr); - void __fastcall UpdateBJLList(); - void __fastcall BJLAnalyze(); - bool __fastcall BJLGetIdx(int* idx, int from, int num); - bool __fastcall BJLCheckPattern1(char* t, int from); - bool __fastcall BJLCheckPattern2(char* t, int from); - int __fastcall BJLFindLabel(int address, int* no); - void __fastcall BJLSeqSetStateU(int* idx, int num); - void __fastcall BJLListSetUsed(int from, int num); - char __fastcall ExprGetOperation(String s); - void __fastcall ExprMerge(String& dst, String src, char op); // dst = dst op src, op = '|' or '&' - String __fastcall PrintBJL(); - PDCONTEXT __fastcall GetContext(DWORD Adr); - void __fastcall SaveContext(DWORD Adr); - void __fastcall RestoreContext(DWORD Adr); -}; - -class TDecompiler { -public: - bool WasRet; // Was ret instruction - char CmpOp; // Compare operation - DWORD CmpAdr; // Compare dest address - int _ESP_; // Stack pointer - int _TOP_; // Top of FStack - DISINFO DisInfo; - CMPITEM CmpInfo; - TDecompileEnv *Env; - BYTE *DeFlags; - PITEM Stack; - - __fastcall TDecompiler(TDecompileEnv* AEnv); - __fastcall ~TDecompiler(); - bool __fastcall CheckPrototype(PInfoRec ARec); - void __fastcall ClearStop(DWORD Adr); - DWORD __fastcall Decompile(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo); - DWORD __fastcall DecompileCaseEnum(DWORD fromAdr, int N, PLoopInfo loopInfo); - DWORD __fastcall DecompileGeneralCase(DWORD fromAdr, DWORD markAdr, PLoopInfo loopInfo, int N); - DWORD __fastcall DecompileTry(DWORD fromAdr, DWORD flags, PLoopInfo loopInfo); - PITEM __fastcall FGet(int idx); - PITEM __fastcall FPop(); - void __fastcall FPush(PITEM val); - void __fastcall FSet(int idx, PITEM val); - void __fastcall FXch(int idx1, int idx2); - int __fastcall GetArrayFieldOffset(String ATypeName, int AFromOfs, int AScale, String& _name, String& _type); - int __fastcall GetCmpInfo(DWORD fromAdr); - String __fastcall GetCycleFrom(); - void __fastcall GetCycleIdx(PIDXINFO IdxInfo, DISINFO* ADisInfo); - String __fastcall GetCycleTo(); - void __fastcall GetFloatItemFromStack(int Esp, PITEM Dst, int FloatType); - String __fastcall GetStringArgument(PITEM item); - PLoopInfo __fastcall GetLoopInfo(int fromAdr); - void __fastcall GetMemItem(int CurAdr, PITEM Dst, BYTE Op); - void __fastcall GetRegItem(int Idx, PITEM Dst); - String __fastcall GetRegType(int Idx); - String __fastcall GetSysCallAlias(String AName); - bool __fastcall Init(DWORD fromAdr); - void __fastcall InitFlags(); - void __fastcall MarkCaseEnum(DWORD fromAdr); - void __fastcall MarkGeneralCase(DWORD fromAdr); - PITEM __fastcall Pop(); - void __fastcall Push(PITEM item); - void __fastcall SetStackPointers(TDecompiler* ASrc); - void __fastcall SetDeFlags(BYTE* ASrc); - void __fastcall SetRegItem(int Idx, PITEM Val); - void __fastcall SetStop(DWORD Adr); - bool __fastcall SimulateCall(DWORD curAdr, DWORD callAdr, int instrLen, PMethodRec recM, DWORD AClassAdr); - void __fastcall SimulateFloatInstruction(DWORD curAdr, int instrLen); - void __fastcall SimulateFormatCall(); - void __fastcall SimulateInherited(DWORD procAdr); - void __fastcall SimulateInstr1(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr2(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr2RegImm(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr2RegMem(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr2RegReg(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr2MemImm(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr2MemReg(DWORD curAdr, BYTE Op); - void __fastcall SimulateInstr3(DWORD curAdr, BYTE Op); - void __fastcall SimulatePop(DWORD curAdr); - void __fastcall SimulatePush(DWORD curAdr, bool bShowComment); - bool __fastcall SimulateSysCall(String name, DWORD procAdr, int instrLen); - int __fastcall AnalyzeConditions(int brType, DWORD curAdr, DWORD sAdr, DWORD jAdr, PLoopInfo loopInfo); -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Disasm.h b/Sources/Libs/Disasm.h deleted file mode 100644 index 74d58cf..0000000 --- a/Sources/Libs/Disasm.h +++ /dev/null @@ -1,134 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef DisasmH -#define DisasmH -// --------------------------------------------------------------------------- -#define ASMMAXCOPLEN 12 -// Instruction type -#define itUnknown 0 //Unknown instruction -#define itTransfer 1 //Data transfer instruction -#define itArifm 2 //Ariphmetical instruction -#define itLogic 3 //Logical instruction -#define itControl 4 //Control flow instruction -#define itString 5 //String instruction -#define itFloat 6 //Coprocessor instruction - -typedef struct { - char Mnem[32]; - char Op1[64]; - // char Op2[64]; - // char Op3[64]; - // BYTE InstrType; - bool Float; - bool Call; - bool Branch; - bool Conditional; - bool Ret; - // Register indexes, used as operands - int OpRegIdx[3]; - // [BaseReg + IndxReg*Scale + Offset] - int BaseReg; - int IndxReg; - int Scale; - DWORD Offset; - // - // bool ImmPresent; - DWORD Immediate; - BYTE OpSize; // Operand size - // BYTE ImmSize;//size of immediate operand - char sSize[32]; - int RepPrefix; - int SegPrefix; - BYTE OpNum; - BYTE OpType[3]; - // BYTE Op1Type; - // BYTE Op2Type; - // BYTE Op3Type; -} DISINFO, *PDISINFO; - -#define otUND 0 -#define otIMM 1 -#define otREG 2 -#define otMEM 3 -#define otFST 4 - -#define OP_RESET 0x80 -#define OP_A2 0x40 //2 or 3 operands - -#define OP_UNK 0 -#define OP_ADC 0x81 //1 OP_RESET -#define OP_ADD 0xC2 //2 OP_RESET OP_A2 -#define OP_AND 0xC3 //3 OP_RESET OP_A2 -#define OP_BT 0x44 //4 OP_A2 -#define OP_BTC 0x45 //5 OP_A2 -#define OP_BTR 0x46 //6 OP_A2 -#define OP_BTS 0x47 //7 OP_A2 -#define OP_CDQ 0x88 //8 OP_RESET -#define OP_CMP 0x49 //9 OP_A2 -#define OP_DEC 0x8A //A OP_RESET -#define OP_DIV 0x8B //B OP_RESET -#define OP_IDIV 0xCC //C OP_RESET OP_A2 -#define OP_IMUL 0xCD //D OP_RESET OP_A2 -#define OP_INC 0x8E //E OP_RESET -#define OP_JMP 0x8F //F OP_RESET -#define OP_LEA 0xD0 //10 OP_RESET OP_A2 -#define OP_MOV 0xD1 //11 OP_RESET OP_A2 -#define OP_MOVS 0x92 //12 OP_RESET -#define OP_MUL 0x93 //13 OP_RESET -#define OP_NEG 0x94 //14 OP_RESET -#define OP_OR 0xD5 //15 OP_RESET OP_A2 -#define OP_POP 0x96 //16 OP_RESET -#define OP_PUSH 0x97 //17 OP_RESET -#define OP_SAR 0x98 //18 OP_RESET -#define OP_SBB 0x99 //19 OP_RESET -#define OP_SET 0x9A //1A OP_RESET -#define OP_SUB 0x9B //1B OP_RESET -#define OP_TEST 0x5C //1C OP_A2 -#define OP_XCHG 0xDD //1D OP_RESET OP_A2 -#define OP_XOR 0xDE //1E OP_RESET OP_A2 -#define OP_SHR 0x9F //1F OP_RESET -#define OP_SAL 0xA0 //20 OP_RESET -#define OP_SHL 0xA1 //21 OP_RESET -#define OP_NOT 0xA2 //22 OP_RESET - -class MDisasm { -public: - __fastcall MDisasm(); - __fastcall ~MDisasm(); - int __fastcall Init(); - int __fastcall Disassemble(DWORD fromAdr, PDISINFO pDisInfo, char* disLine); - int __fastcall Disassemble(BYTE* from, __int64 address, PDISINFO pDisInfo, char* disLine); - int __fastcall GetRegister(char* reg); - - HINSTANCE hModule; - - BYTE __fastcall GetOp(char* mnem); - BYTE __fastcall GetCop(); - BYTE __fastcall GetCop1(); - BYTE __fastcall GetPostByte(); - void __fastcall SetPostByte(BYTE b); - void __fastcall SetOffset(DWORD ofs); - void __fastcall GetInstrBytes(BYTE* dst); - char* __fastcall GetSizeString(int size); - -private: - bool __fastcall GetAddressSize(); - bool __fastcall GetOperandSize(); - BYTE __fastcall GetSegPrefix(); - BYTE __fastcall GetRepPrefix(); - BYTE __fastcall GetPostByteMod(); - int __fastcall GetPostByteReg(); - int __fastcall GetPostByteRm(); - int __fastcall GetOpType(char* Op); - void __fastcall FormatInstr(PDISINFO pDisInfo, char* disLine); - void __fastcall FormatArg(int argno, DWORD cmd, DWORD arg, PDISINFO pDisInfo, char* disLine); - int __fastcall OutputGeneralRegister(char *dst, int reg, int size); - void __fastcall OutputHex(char *dst, DWORD val); - DWORD __fastcall GetAddress(); - void __fastcall OutputSegPrefix(char* dst, PDISINFO pDisInfo); - int __fastcall EvaluateOperandSize(); - void __fastcall OutputSizePtr(int size, bool mm, PDISINFO pDisInfo, char* disLine); - void __fastcall OutputMemAdr16(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine); - void __fastcall OutputMemAdr32(int argno, char* dst, DWORD arg, bool f1, bool f2, PDISINFO pDisInfo, char* disLine); -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/IDCGen.cpp b/Sources/Libs/IDCGen.cpp deleted file mode 100644 index 6dd9d8c..0000000 --- a/Sources/Libs/IDCGen.cpp +++ /dev/null @@ -1,1277 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Misc.h" -#include "IDCGen.h" -// --------------------------------------------------------------------------- -extern MDisasm Disasm; -extern DWORD CodeBase; -extern BYTE *Code; -extern int DelphiVersion; -extern DWORD *Flags; -extern PInfoRec *Infos; -extern bool SplitIDC; - -// --------------------------------------------------------------------------- -__fastcall TIDCGen::TIDCGen(FILE* FIdc, int splitSize) { - idcF = FIdc; - unitName = ""; - itemName = ""; - names = new TStringList; - repeated = new TList; - SplitSize = splitSize; - CurrentPartNo = 1; - CurrentBytes = 0; -} - -// --------------------------------------------------------------------------- -__fastcall TIDCGen::~TIDCGen() { - delete names; - delete repeated; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::NewIDCPart(FILE* FIdc) { - idcF = FIdc; - CurrentBytes = 0; - CurrentPartNo++; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::DeleteName(int pos) { - DWORD adr = Pos2Adr(pos); - - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"\", 0);\n", adr); -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeByte(int pos) { - CurrentBytes += fprintf(idcF, "MakeByte(0x%lX);\n", Pos2Adr(pos)); - return pos + 1; -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeWord(int pos) { - CurrentBytes += fprintf(idcF, "MakeWord(0x%lX);\n", Pos2Adr(pos)); - return pos + 2; -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeDword(int pos) { - CurrentBytes += fprintf(idcF, "MakeDword(0x%lX);\n", Pos2Adr(pos)); - return pos + 4; -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeQword(int pos) { - CurrentBytes += fprintf(idcF, "MakeQword(0x%lX);\n", Pos2Adr(pos)); - return pos + 8; -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeArray(int pos, int num) { - CurrentBytes += fprintf(idcF, "MakeByte(0x%lX);\n", Pos2Adr(pos)); - CurrentBytes += fprintf(idcF, "MakeArray(0x%lX, %d);\n", Pos2Adr(pos), num); - return pos + num; -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeShortString(int pos) { - BYTE len = Code[pos]; - // Empty String - if (!len) - return pos + 1; - - if (!IsValidName(len, pos + 1)) - return pos; - - CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_PASCAL);\n"); - CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, 0x%lX);\n", Pos2Adr(pos), Pos2Adr(pos) + len + 1); - return pos + len + 1; -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeCString(int pos) { - int len = strlen(Code + pos); - CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_TERMCHR);\n"); - CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, 0x%lX);\n", Pos2Adr(pos), Pos2Adr(pos) + len + 1); - return pos + len + 1; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::MakeLString(int pos) { - CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_TERMCHR);\n"); - CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, -1);\n", Pos2Adr(pos)); - // Length - MakeDword(pos - 4); - // RefCount - MakeDword(pos - 8); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::MakeWString(int pos) { - CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);\n"); - CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, -1);\n", Pos2Adr(pos)); - // Length - MakeDword(pos - 4); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::MakeUString(int pos) { - CurrentBytes += fprintf(idcF, "SetLongPrm(INF_STRTYPE, ASCSTR_UNICODE);\n"); - CurrentBytes += fprintf(idcF, "MakeStr(0x%lX, -1);\n", Pos2Adr(pos)); - // Length - MakeDword(pos - 4); - // RefCount - MakeDword(pos - 8); - // Word - MakeWord(pos - 10); - // CodePage - MakeWord(pos - 12); -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::MakeCode(int pos) { - DISINFO DisInfo; - - CurrentBytes += fprintf(idcF, "MakeCode(0x%lX);\n", Pos2Adr(pos)); - int instrLen = Disasm.Disassemble(Code + pos, (__int64)Pos2Adr(pos), 0, 0); - if (!instrLen) - instrLen = 1; - return instrLen; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::MakeFunction(DWORD adr) { - if (adr) { - CurrentBytes += fprintf(idcF, "MakeFunction(0x%lX, -1);\n", adr); - MakeCode(Adr2Pos(adr)); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::MakeComment(int pos, String text) { - CurrentBytes += fprintf(idcF, "MakeComm(0x%lX, \"%s\");\n", Pos2Adr(pos), TransformString(AnsiString(text).c_str(), text.Length()).c_str()); -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::OutputAttrData(int pos) { - WORD dw = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - return pos; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputHeaderFull() { - CurrentBytes += fprintf(idcF, "#include \n"); - CurrentBytes += fprintf(idcF, "static clear(from){\n"); - CurrentBytes += fprintf(idcF, "auto ea;\n"); - CurrentBytes += fprintf(idcF, "ea = from;\n"); - CurrentBytes += fprintf(idcF, "while (1){\n"); - CurrentBytes += fprintf(idcF, "ea = NextFunction(ea);\n"); - CurrentBytes += fprintf(idcF, "if (ea == -1) break;\n"); - CurrentBytes += fprintf(idcF, "DelFunction(ea);\n"); - CurrentBytes += fprintf(idcF, "MakeNameEx(ea, \"\", 0);}\n"); - CurrentBytes += fprintf(idcF, "ea = from;\n"); - CurrentBytes += fprintf(idcF, "while (1){\n"); - CurrentBytes += fprintf(idcF, "ea = FindExplored(ea, SEARCH_DOWN | SEARCH_NEXT);\n"); - CurrentBytes += fprintf(idcF, "if (ea == -1) break;\n"); - CurrentBytes += fprintf(idcF, "MakeUnkn(ea, 1);}\n"); - CurrentBytes += fprintf(idcF, "}\n"); - CurrentBytes += fprintf(idcF, "static main(){\n"); - CurrentBytes += fprintf(idcF, "clear(0x%lX);\n", CodeBase); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputHeaderShort() { - CurrentBytes += fprintf(idcF, "#include \n"); - CurrentBytes += fprintf(idcF, "static main(){\n"); -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::OutputRTTIHeader(BYTE kind, int pos) { - int fromPos = pos; - - BYTE len = *(Code + pos + 5); - itemName = String((char*)(Code + pos + 6), len); - DWORD adr = Pos2Adr(pos); - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"RTTI_%lX_%s_%s\", 0);\n", adr, adr, TypeKind2Name(kind).c_str(), itemName.c_str()); - // Selfptr - pos = MakeDword(pos); - // Kind - // Delete name (often presents) - DeleteName(pos); - pos = MakeByte(pos); - // Name - pos = MakeShortString(pos); - return pos - fromPos; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIInteger(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // ordType - pos = MakeByte(pos); - // minValue - pos = MakeDword(pos); - // maxValue - pos = MakeDword(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIChar(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // ordType - pos = MakeByte(pos); - // minValue - pos = MakeDword(pos); - // maxValue - pos = MakeDword(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIEnumeration(BYTE kind, int pos, DWORD adr) { - pos += OutputRTTIHeader(kind, pos); - // ordType - pos = MakeByte(pos); - // minValue - DWORD minValue = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - // maxValue - DWORD maxValue = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - // baseTypeAdr - DWORD baseTypeAdr = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - - if (baseTypeAdr == adr) { - if (SameText(itemName, "ByteBool") || SameText(itemName, "WordBool") || SameText(itemName, "LongBool")) { - minValue = 0; - maxValue = 1; - } - - for (int n = minValue; n <= maxValue; n++) { - pos = MakeShortString(pos); - } - } - // UnitName - // pos = MakeShortString(pos); - // if (DelphiVersion == 2010) OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIFloat(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // FloatType - pos = MakeByte(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIString(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // MaxLength - pos = MakeByte(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTISet(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // OrdType - pos = MakeByte(pos); - // CompType - pos = MakeDword(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIClass(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // classVMT - pos = MakeDword(pos); - // ParentInfo - pos = MakeDword(pos); - // PropCount - pos = MakeWord(pos); - // UnitName - pos = MakeShortString(pos); - // PropData - WORD Count = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - for (int n = 0; n < Count; n++) { - // TPropInfo - for (int m = 0; m < 6; m++) { - pos = MakeDword(pos); - } - pos = MakeWord(pos); - pos = MakeShortString(pos); - } - if (DelphiVersion >= 2010) { - // PropDataEx - Count = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - for (int n = 0; n < Count; n++) { - // Flags - pos = MakeByte(pos); - // Info - DWORD typeInfo = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - for (int m = 0; m < 6; m++) { - MakeDword(Adr2Pos(typeInfo)); - typeInfo += 4; - } - MakeWord(Adr2Pos(typeInfo)); - typeInfo += 2; - MakeShortString(Adr2Pos(typeInfo)); - // AttrData - pos = OutputAttrData(pos); - } - // AttrData - OutputAttrData(pos); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIMethod(BYTE kind, int pos) { - int _pos = pos, pos1; - - pos += OutputRTTIHeader(kind, pos); - // MethodKind - BYTE methodKind = Code[pos]; - pos = MakeByte(pos); - // ParamCnt - BYTE paramCnt = Code[pos]; - pos = MakeByte(pos); - - for (int n = 0; n < paramCnt; n++) { - // Flags - pos = MakeByte(pos); - // ParamName - pos = MakeShortString(pos); - // TypeName - pos = MakeShortString(pos); - } - - if (methodKind) { - // ResultType - pos = MakeShortString(pos); - if (DelphiVersion > 6) { - // ResultTypeRef - pos = MakeDword(pos); - } - } - - if (DelphiVersion > 6) { - // CC (TCallConv) - pos = MakeByte(pos); - // ParamTypeRefs - for (int n = 0; n < paramCnt; n++) { - pos = MakeDword(pos); - } - if (DelphiVersion >= 2010) { - DWORD procSig = *((DWORD*)(Code + pos)); - // MethSig - pos = MakeDword(pos); - // AttrData - OutputAttrData(pos); - // Procedure Signature - if (procSig) { - if (IsValidImageAdr(procSig)) - pos1 = Adr2Pos(procSig); - else - pos1 = _pos + procSig; - // Flags - BYTE flags = Code[pos1]; - pos1 = MakeByte(pos1); - if (flags != 0xFF) { - // CC - pos1 = MakeByte(pos1); - // ResultType - pos1 = MakeDword(pos1); - // ParamCount - paramCnt = Code[pos1]; - pos1 = MakeByte(pos1); - for (int n = 0; n < paramCnt; n++) { - // Flags - pos1 = MakeByte(pos1); - // ParamType - pos1 = MakeDword(pos1); - // Name - pos1 = MakeShortString(pos1); - // AttrData - pos1 = OutputAttrData(pos1); - } - } - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIWChar(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // ordType - pos = MakeByte(pos); - // minValue - pos = MakeDword(pos); - // maxValue - pos = MakeDword(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTILString(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - if (DelphiVersion >= 2009) { - // CodePage - pos = MakeWord(pos); - } - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIWString(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIVariant(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIArray(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // Size - pos = MakeDword(pos); - // ElCount - pos = MakeDword(pos); - // ElType - pos = MakeDword(pos); - - if (DelphiVersion >= 2010) { - // DimCount - BYTE dimCnt = Code[pos]; - pos = MakeByte(pos); - for (int n = 0; n < dimCnt; n++) { - // Dims - pos = MakeDword(pos); - } - // AttrData - OutputAttrData(pos); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIRecord(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // Size - pos = MakeDword(pos); - // ManagedFldCount - int n, m, elNum = *((int*)(Code + pos)); - pos = MakeDword(pos); - for (n = 0; n < elNum; n++) { - // TypeRef - pos = MakeDword(pos); - // FldOffset - pos = MakeDword(pos); - } - - if (DelphiVersion >= 2010) { - // NumOps - BYTE numOps = Code[pos]; - pos = MakeByte(pos); - for (n = 0; n < numOps; n++) // RecOps - { - pos = MakeDword(pos); - } - // RecFldCnt - elNum = *((int*)(Code + pos)); - pos = MakeDword(pos); - - for (n = 0; n < elNum; n++) { - // TypeRef - pos = MakeDword(pos); - // FldOffset - pos = MakeDword(pos); - // Flags - pos = MakeByte(pos); - // Name - pos = MakeShortString(pos); - // AttrData - pos = OutputAttrData(pos); - } - // AttrData - pos = OutputAttrData(pos); - if (DelphiVersion >= 2012) { - WORD methCnt = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - for (n = 0; n < methCnt; n++) { - // Flags - pos = MakeByte(pos); - // Code - pos = MakeDword(pos); - // Name - pos = MakeShortString(pos); - // ProcedureSignature - // Flags - BYTE flags = Code[pos]; - pos = MakeByte(pos); - if (flags != 0xFF) { - // CC - pos = MakeByte(pos); - // ResultType - pos = MakeDword(pos); - BYTE paramCnt = Code[pos]; - pos = MakeByte(pos); - // Params - for (m = 0; m < paramCnt; m++) { - // Flags - pos = MakeByte(pos); - // ParamType - pos = MakeDword(pos); - // Name - pos = MakeShortString(pos); - // AttrData - pos = OutputAttrData(pos); - } - } - // AttrData - pos = OutputAttrData(pos); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIInterface(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // IntfParent - pos = MakeDword(pos); - // IntfFlags - pos = MakeByte(pos); - // GUID - pos = MakeArray(pos, 16); - // UnitName - pos = MakeShortString(pos); - // PropCount - WORD Count = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - - if (DelphiVersion >= 6) { - // RttiCount - WORD dw = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - if (dw != 0xFFFF) { - if (DelphiVersion >= 2010) { - for (int n = 0; n < Count; n++) { - // Name - pos = MakeShortString(pos); - // Kind - BYTE methodKind = Code[pos]; - pos = MakeByte(pos); - // CallConv - pos = MakeByte(pos); - // ParamCount - BYTE paramCnt = Code[pos]; - pos = MakeByte(pos); - - for (int m = 0; m < paramCnt; m++) { - // Flags - pos = MakeByte(pos); - // ParamName - pos = MakeShortString(pos); - // TypeName - pos = MakeShortString(pos); - // ParamType - pos = MakeDword(pos); - } - if (methodKind) { - // ResultTypeName - BYTE len = Code[pos]; - pos = MakeShortString(pos); - if (len) { - // ResultType - pos = MakeDword(pos); - } - } - } - } - else { - for (int n = 0; n < Count; n++) { - // PropType - pos = MakeDword(pos); - // GetProc - pos = MakeDword(pos); - // SetProc - pos = MakeDword(pos); - // StoredProc - pos = MakeDword(pos); - // Index - pos = MakeDword(pos); - // Default - pos = MakeDword(pos); - // NameIndex - pos = MakeWord(pos); - // Name - pos = MakeShortString(pos); - } - } - } - if (DelphiVersion >= 2010) { - // AttrData - OutputAttrData(pos); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIInt64(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // MinVal - pos = MakeQword(pos); - // MaxVal - pos = MakeQword(pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIDynArray(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // elSize - pos = MakeDword(pos); - // elType - pos = MakeDword(pos); - // varType - pos = MakeDword(pos); - - if (DelphiVersion >= 6) { - // elType2 - pos = MakeDword(pos); - // UnitName - pos = MakeShortString(pos); - } - if (DelphiVersion >= 2010) { - // DynArrElType - pos = MakeDword(pos); - // AttrData - OutputAttrData(pos); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIUString(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - if (DelphiVersion >= 2010) - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIClassRef(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // InstanceType - pos = MakeDword(pos); - // AttrData - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIPointer(BYTE kind, int pos) { - pos += OutputRTTIHeader(kind, pos); - // RefType - pos = MakeDword(pos); - // AttrData - OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputRTTIProcedure(BYTE kind, int pos) { - int _pos = pos; - - pos += OutputRTTIHeader(kind, pos); - // MethSig - DWORD procSig = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - // AttrData - pos = OutputAttrData(pos); - // Procedure Signature - if (procSig) { - if (IsValidImageAdr(procSig)) - pos = Adr2Pos(procSig); - else - pos = _pos + procSig; - // Flags - BYTE flags = Code[pos]; - pos = MakeByte(pos); - if (flags != 0xFF) { - // CallConv - pos = MakeByte(pos); - // ResultType - pos = MakeDword(pos); - // ParamCnt - BYTE paramCnt = Code[pos]; - pos = MakeByte(pos); - for (int n = 0; n < paramCnt; n++) { - // Flags - pos = MakeByte(pos); - // ParamType - pos = MakeDword(pos); - // Name - pos = MakeShortString(pos); - // AttrData - pos = OutputAttrData(pos); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputVMT(int pos, PInfoRec recN) { - itemName = recN->GetName(); - pos += OutputVMTHeader(pos, itemName); - if (DelphiVersion >= 3) { - // VmtIntfTable - OutputIntfTable(pos); - pos += 4; - // VmtAutoTable - OutputAutoTable(pos); - pos += 4; - } - // VmtInitTable - OutputInitTable(pos); - pos += 4; - // VmtTypeInfo - pos = MakeDword(pos); - // VmtFieldTable - OutputFieldTable(pos); - pos += 4; - // VmtMethodTable - OutputMethodTable(pos); - pos += 4; - // VmtDynamicTable - OutputDynamicTable(pos); - pos += 4; - // VmtClassName - DWORD nameAdr = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - MakeShortString(Adr2Pos(nameAdr)); - // VmtInstanceSize - pos = MakeDword(pos); - // VmtParent - pos = MakeDword(pos); - if (DelphiVersion >= 2009) { - // VmtEquals - pos = MakeDword(pos); - // VmtGetHashCode - pos = MakeDword(pos); - // VmtToString - pos = MakeDword(pos); - } - if (DelphiVersion >= 3) { - // VmtSafeCallException - pos = MakeDword(pos); - } - if (DelphiVersion >= 4) { - // VmtAfterConstruction - pos = MakeDword(pos); - // VmtBeforeDestruction - pos = MakeDword(pos); - // VmtDispatch - pos = MakeDword(pos); - } - // VmtDefaultHandler - pos = MakeDword(pos); - // VmtNewInstance - pos = MakeDword(pos); - // VmtFreeInstance - pos = MakeDword(pos); - // VmtDestroy - pos = MakeDword(pos); - // Vmt - int stopPos = Adr2Pos(GetStopAt(Pos2Adr(pos))); - // Virtual Methods - int ofs = 0; - while (pos < stopPos) { - MakeComment(pos, "+" + Val2Str0(ofs)); - ofs += 4; - pos = MakeDword(pos); - } -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::OutputVMTHeader(int pos, String vmtName) { - int fromPos = pos; - DWORD adr = Pos2Adr(pos); - - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"VMT_%lX_%s\", 0);\n", adr, adr, vmtName.c_str()); - // VmtSelfPtr - pos = MakeDword(pos); - return pos - fromPos; -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputIntfTable(int pos) { - MakeDword(pos); - DWORD intfTable = *((DWORD*)(Code + pos)); - if (intfTable) { - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", intfTable); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_IntfTable\", 0);\n", intfTable, itemName.c_str()); - pos = Adr2Pos(intfTable); - // EntryCount - DWORD EntryCount = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - for (int n = 0; n < EntryCount; n++) { - // GUID - pos = MakeArray(pos, 16); - // vTableAdr - OutputIntfVTable(pos, intfTable); - pos += 4; - // IOffset - pos = MakeDword(pos); - if (DelphiVersion > 3) { - // ImplGetter - pos = MakeDword(pos); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputIntfVTable(int pos, DWORD stopAdr) { - MakeDword(pos); - DWORD vTableAdr = *((DWORD*)(Code + pos)); - if (vTableAdr) { - int pos = Adr2Pos(vTableAdr); - // CC byte address - DWORD CCadr = vTableAdr; - for (int n = 0; ; n++) { - if (Pos2Adr(pos) == stopAdr) - break; - DWORD vAdr = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - MakeFunction(vAdr); - if (vAdr && vAdr < CCadr) - CCadr = vAdr; - } - CCadr--; - MakeByte(Adr2Pos(CCadr)); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputAutoTable(int pos) { - MakeDword(pos); - DWORD autoTable = *((DWORD*)(Code + pos)); - if (autoTable) { - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", autoTable); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_AutoTable\", 0);\n", autoTable, itemName.c_str()); - pos = Adr2Pos(autoTable); - // EntryCount - DWORD EntryCount = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - for (int n = 0; n < EntryCount; n++) { - // DispID - pos = MakeDword(pos); - // NameAdr - pos = MakeDword(pos); - // Flags - pos = MakeDword(pos); - // ParamsAdr - OutputAutoPTable(pos); - pos += 4; - // ProcAdr - // DWORD procAdr = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - // MakeFunction(procAdr); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputAutoPTable(int pos) { - MakeDword(pos); - DWORD paramsAdr = *((DWORD*)(Code + pos)); - if (paramsAdr) { - pos = Adr2Pos(paramsAdr); - BYTE paramCnt = Code[pos + 1]; - MakeArray(Adr2Pos(paramsAdr), paramCnt + 2); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputInitTable(int pos) { - MakeDword(pos); - DWORD initTable = *((DWORD*)(Code + pos)); - if (initTable) { - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", initTable); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_InitTable\", 0);\n", initTable, itemName.c_str()); - pos = Adr2Pos(initTable); - // 0xE - pos = MakeByte(pos); - // Unknown byte - pos = MakeByte(pos); - // Unknown dword - pos = MakeDword(pos); - // num - DWORD num = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - - for (int n = 0; n < num; n++) { - // TypeOfs - pos = MakeDword(pos); - // FieldOfs - pos = MakeDword(pos); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputFieldTable(int pos) { - MakeDword(pos); - DWORD fieldTable = *((DWORD*)(Code + pos)); - if (fieldTable) { - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", fieldTable); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_FieldTable\", 0);\n", fieldTable, itemName.c_str()); - pos = Adr2Pos(fieldTable); - // num - WORD num = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - // TypesTab - OutputFieldTTable(pos); - pos += 4; - for (int n = 0; n < num; n++) { - // Offset - pos = MakeDword(pos); - // Idx - pos = MakeWord(pos); - // Name - pos = MakeShortString(pos); - } - if (DelphiVersion >= 2010) { - // num - num = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - - for (int n = 0; n < num; n++) { - // Flags - pos = MakeByte(pos); - // TypeRef - pos = MakeDword(pos); - // Offset - pos = MakeDword(pos); - // Name - pos = MakeShortString(pos); - // AttrData - pos = OutputAttrData(pos); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputFieldTTable(int pos) { - MakeDword(pos); - DWORD typesTab = *((DWORD*)(Code + pos)); - if (typesTab) { - pos = Adr2Pos(typesTab); - // num - WORD num = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - for (int n = 0; n < num; n++) - pos = MakeDword(pos); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputMethodTable(int pos) { - MakeDword(pos); - DWORD methodTable = *((DWORD*)(Code + pos)); - if (methodTable) { - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", methodTable); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_MethodTable\", 0);\n", methodTable, itemName.c_str()); - pos = Adr2Pos(methodTable); - // Count - WORD count = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - - for (int n = 0; n < count; n++) { - // Len - WORD len = *((WORD*)(Code + pos)); - int endpos = pos + len; - pos = MakeWord(pos); - // CodeAddress - // DWORD codeAdr = *((WORD*)(Code + pos)); - pos = MakeDword(pos); - // MakeFunction(codeAdr); - // Name - pos = MakeShortString(pos); - // Tail - if (pos < endpos) { - OutputVmtMethodEntryTail(pos); - pos = endpos; - } - } - if (DelphiVersion >= 2010) { - // ExCount - WORD excount = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - - for (int n = 0; n < excount; n++) { - // Entry - OutputVmtMethodEntry(pos); - pos += 4; - // Flags - pos = MakeWord(pos); - // VirtualIndex - pos = MakeWord(pos); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputVmtMethodEntry(int pos) { - MakeDword(pos); - DWORD entry = *((DWORD*)(Code + pos)); - if (entry) { - pos = Adr2Pos(entry); - // Len - WORD len = *((WORD*)(Code + pos)); - int endpos = pos + len; - pos = MakeWord(pos); - // CodeAddress - // DWORD codeAdr = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - // MakeFunction(codeAdr); - // Name - pos = MakeShortString(pos); - // Tail - if (pos < endpos) - pos = OutputVmtMethodEntryTail(pos); - } -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::OutputVmtMethodEntryTail(int pos) { - // Version - pos = MakeByte(pos); - // CC - pos = MakeByte(pos); - // ResultType - pos = MakeDword(pos); - // ParOff - pos = MakeWord(pos); - // ParamCount - BYTE paramCnt = Code[pos]; - pos = MakeByte(pos); - - for (int n = 0; n < paramCnt; n++) { - // Flags - pos = MakeByte(pos); - // ParamType - pos = MakeDword(pos); - // ParOff - pos = MakeWord(pos); - // Name - pos = MakeShortString(pos); - // AttrData - pos = OutputAttrData(pos); - } - // AttrData - return OutputAttrData(pos); -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputDynamicTable(int pos) { - MakeDword(pos); - DWORD dynamicTable = *((DWORD*)(Code + pos)); - if (dynamicTable) { - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", dynamicTable); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_DynamicTable\", 0);\n", dynamicTable, itemName.c_str()); - pos = Adr2Pos(dynamicTable); - // Num - WORD num = *((WORD*)(Code + pos)); - pos = MakeWord(pos); - - for (int n = 0; n < num; n++) { - // Msg - pos = MakeWord(pos); - } - for (int n = 0; n < num; n++) { - // ProcAddress - pos = MakeDword(pos); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputResString(int pos, PInfoRec recN) { - itemName = recN->GetName(); - MakeComment(pos, itemName); - pos = MakeDword(pos); - pos = MakeDword(pos); -} - -// --------------------------------------------------------------------------- -int __fastcall TIDCGen::OutputProc(int pos, PInfoRec recN, bool imp) { - itemName = recN->GetName(); - int fromPos = pos; - DWORD fromAdr = Pos2Adr(pos); - - if (itemName != "") { - int idx = names->IndexOf(itemName); - if (idx == -1) { - names->Add(itemName); - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", fromAdr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s\", 0x20);\n", fromAdr, itemName.c_str()); - // CurrentBytes += fprintf(idcF, "ApplyType(0x%lX, \"%s\", 0);\n", fromAdr, recN->MakeIDCPrototype(...)); - } - else { - PREPNAMEINFO info = GetNameInfo(idx); - if (!info) { - info = new REPNAMEINFO; - info->index = idx; - info->counter = 0; - repeated->Add((void*)info); - } - int cnt = info->counter; - info->counter++; - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", fromAdr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_%d\", 0x20);\n", fromAdr, itemName.c_str(), cnt); - // CurrentBytes += fprintf(idcF, "ApplyType(0x%lX, \"%s_%d\", 0);\n", fromAdr, recN->MakeIDCPrototype(...), cnt); - } - MakeComment(pos, recN->MakePrototype(fromAdr, true, false, false, true, false)); - } - int _procSize = GetProcSize(fromAdr); - // If no procedure just return 0; - if (!_procSize) - return 0; - - int instrLen = MakeCode(pos); - if (imp || _procSize == instrLen) { - CurrentBytes += fprintf(idcF, "MakeFunction(0x%lX, 0x%lX);\n", fromAdr, fromAdr + instrLen); - return instrLen - 1; // = procSize - 1 - } - - while (1) { - if (pos - fromPos + 1 == _procSize) { - CurrentBytes += fprintf(idcF, "MakeFunction(0x%lX, 0x%lX);\n", fromAdr, Pos2Adr(pos) + 1); - break; - } - - PInfoRec recN1 = GetInfoRec(Pos2Adr(pos)); - if (recN1 && recN1->picode) - MakeComment(pos, FMain_11011981->MakeComment(recN1->picode)); - - if (IsFlagSet(cfExcept | cfFinally, pos)) { - MakeCode(pos); - pos++; - continue; - } - - if (IsFlagSet(cfETable, pos)) { - DWORD num = *((DWORD*)(Code + pos)); - pos = MakeDword(pos); - for (int n = 0; n < num; n++) { - pos = MakeDword(pos); // ExceptionInfo - pos = MakeDword(pos); // ExceptionProc - } - continue; - } - if (IsFlagSet(cfLoc, pos) && (pos != fromPos)) { - MakeCode(pos); - pos++; - continue; - } - pos++; - } - return pos - fromPos; // = procSize - 1 -} - -// --------------------------------------------------------------------------- -void __fastcall TIDCGen::OutputData(int pos, PInfoRec recN) { - if (recN->HasName()) { - MakeByte(pos); - if (recN->type == "" || (!SameText(recN->type, "Single") && !SameText(recN->type, "Double") && !SameText(recN->type, "Extended") && !SameText(recN->type, "Comp") && !SameText(recN->type, - "Currency"))) { - String _name = recN->GetName(); - int idx = names->IndexOf(_name); - DWORD adr = Pos2Adr(pos); - if (idx == -1) { - names->Add(_name); - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s\", 0);\n", adr, _name.c_str()); - } - else { - PREPNAMEINFO info = GetNameInfo(idx); - if (!info) { - info = new REPNAMEINFO; - info->index = idx; - info->counter = 0; - repeated->Add((void*)info); - } - int cnt = info->counter; - info->counter++; - CurrentBytes += fprintf(idcF, "MakeUnkn(0x%lX, 1);\n", adr); - CurrentBytes += fprintf(idcF, "MakeNameEx(0x%lX, \"%s_%d\", 0);\n", adr, _name.c_str(), cnt); - } - } - if (recN->type != "") - MakeComment(pos, recN->type.c_str()); - } -} - -// --------------------------------------------------------------------------- -PREPNAMEINFO __fastcall TIDCGen::GetNameInfo(int idx) { - int num = repeated->Count; - for (int n = 0; n < num; n++) { - PREPNAMEINFO info = (PREPNAMEINFO)repeated->Items[n]; - if (info->index == idx) - return info; - } - return 0; -} - -// --------------------------------------------------------------------------- -__fastcall TSaveIDCDialog::TSaveIDCDialog(TComponent* AOwner, char* TemplateName) : TOpenDialog(AOwner) { - Options >> ofEnableSizing; - Template = String(TemplateName).c_str(); - CheckDlgButton(Handle, 101, SplitIDC ? BST_CHECKED : BST_UNCHECKED); -} - -// --------------------------------------------------------------------------- -void __fastcall TSaveIDCDialog::WndProc(TMessage& Message) { - switch (Message.Msg) { - case WM_COMMAND: - switch (Message.WParamLo) { - case 101: - if (IsDlgButtonChecked(Handle, 101) == BST_CHECKED) - SplitIDC = true; - else - SplitIDC = false; - break; - }; - break; - }; - TOpenDialog::WndProc(Message); -}; -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/IDCGen.h b/Sources/Libs/IDCGen.h deleted file mode 100644 index 3e89a3f..0000000 --- a/Sources/Libs/IDCGen.h +++ /dev/null @@ -1,92 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef IDCGenH -#define IDCGenH - -#include "Main.h" - -typedef struct { - int index; // Index of name in names - int counter; // Counter -} REPNAMEINFO, *PREPNAMEINFO; - -class TIDCGen { -public: - __fastcall TIDCGen(FILE* FIdc, int splitSize); - __fastcall ~TIDCGen(); - void __fastcall NewIDCPart(FILE* FIdc); - void __fastcall DeleteName(int pos); - int __fastcall MakeByte(int pos); - int __fastcall MakeWord(int pos); - int __fastcall MakeDword(int pos); - int __fastcall MakeQword(int pos); - int __fastcall MakeArray(int pos, int num); - int __fastcall MakeShortString(int pos); - int __fastcall MakeCString(int pos); - void __fastcall MakeLString(int pos); - void __fastcall MakeWString(int pos); - void __fastcall MakeUString(int pos); - int __fastcall MakeCode(int pos); - void __fastcall MakeFunction(DWORD adr); - void __fastcall MakeComment(int pos, String text); - int __fastcall OutputAttrData(int pos); - void __fastcall OutputHeaderFull(); - void __fastcall OutputHeaderShort(); - int __fastcall OutputRTTIHeader(BYTE kind, int pos); - void __fastcall OutputRTTIInteger(BYTE kind, int pos); - void __fastcall OutputRTTIChar(BYTE kind, int pos); - void __fastcall OutputRTTIEnumeration(BYTE kind, int pos, DWORD adr); - void __fastcall OutputRTTIFloat(BYTE kind, int pos); - void __fastcall OutputRTTIString(BYTE kind, int pos); - void __fastcall OutputRTTISet(BYTE kind, int pos); - void __fastcall OutputRTTIClass(BYTE kind, int pos); - void __fastcall OutputRTTIMethod(BYTE kind, int pos); - void __fastcall OutputRTTIWChar(BYTE kind, int pos); - void __fastcall OutputRTTILString(BYTE kind, int pos); - void __fastcall OutputRTTIWString(BYTE kind, int pos); - void __fastcall OutputRTTIVariant(BYTE kind, int pos); - void __fastcall OutputRTTIArray(BYTE kind, int pos); - void __fastcall OutputRTTIRecord(BYTE kind, int pos); - void __fastcall OutputRTTIInterface(BYTE kind, int pos); - void __fastcall OutputRTTIInt64(BYTE kind, int pos); - void __fastcall OutputRTTIDynArray(BYTE kind, int pos); - void __fastcall OutputRTTIUString(BYTE kind, int pos); - void __fastcall OutputRTTIClassRef(BYTE kind, int pos); - void __fastcall OutputRTTIPointer(BYTE kind, int pos); - void __fastcall OutputRTTIProcedure(BYTE kind, int pos); - void __fastcall OutputVMT(int pos, PInfoRec recN); - int __fastcall OutputVMTHeader(int pos, String vmtName); - void __fastcall OutputIntfTable(int pos); - void __fastcall OutputIntfVTable(int pos, DWORD stopAdr); - void __fastcall OutputAutoTable(int pos); - void __fastcall OutputAutoPTable(int pos); - void __fastcall OutputInitTable(int pos); - void __fastcall OutputFieldTable(int pos); - void __fastcall OutputFieldTTable(int pos); - void __fastcall OutputMethodTable(int pos); - void __fastcall OutputVmtMethodEntry(int pos); - int __fastcall OutputVmtMethodEntryTail(int pos); - void __fastcall OutputDynamicTable(int pos); - void __fastcall OutputResString(int pos, PInfoRec recN); - int __fastcall OutputProc(int pos, PInfoRec recN, bool imp); - void __fastcall OutputData(int pos, PInfoRec recN); - PREPNAMEINFO __fastcall GetNameInfo(int idx); - - FILE* idcF; - String unitName; - String itemName; - TStringList* names; - TList* repeated; - int SplitSize; // Maximum output bytes if idc splitted - int CurrentPartNo; // Current part number (filename looks like XXX_NN.idc) - int CurrentBytes; // Current part output bytes -}; - -class TSaveIDCDialog : public TOpenDialog { -public: - __fastcall TSaveIDCDialog(TComponent* AOwner, char* TemplateName); - -protected: - virtual void __fastcall WndProc(Messages::TMessage &Message); -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Infos.cpp b/Sources/Libs/Infos.cpp deleted file mode 100644 index 79977ab..0000000 --- a/Sources/Libs/Infos.cpp +++ /dev/null @@ -1,2759 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include -#include "Infos.h" -#include "Main.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) -// --------------------------------------------------------------------------- -extern MDisasm Disasm; -extern int MaxBufLen; -extern DWORD CodeBase; -extern DWORD *Flags; -extern PInfoRec *Infos; -extern BYTE *Code; -extern TCriticalSection* CrtSection; -extern MKnowledgeBase KnowledgeBase; -extern char StringBuf[MAXSTRBUFFER]; -// as some statistics for memory leaks detection (remove it when fixed) -long stat_InfosOverride = 0; - -// --------------------------------------------------------------------------- -int __fastcall FieldsCmpFunction(void *item1, void *item2) { - PFIELDINFO rec1 = (PFIELDINFO)item1; - PFIELDINFO rec2 = (PFIELDINFO)item2; - if (rec1->Offset > rec2->Offset) - return 1; - if (rec1->Offset < rec2->Offset) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall LocalsCmpFunction(void *item1, void *item2) { - PLOCALINFO rec1 = (PLOCALINFO)item1; - PLOCALINFO rec2 = (PLOCALINFO)item2; - - if (rec1->Ofs > rec2->Ofs) - return 1; - if (rec1->Ofs < rec2->Ofs) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -__fastcall InfoVmtInfo::InfoVmtInfo() { - interfaces = 0; - fields = 0; - methods = 0; -} - -// --------------------------------------------------------------------------- -__fastcall InfoVmtInfo::~InfoVmtInfo() { - if (interfaces) - delete interfaces; - CleanupList(fields); - CleanupList(methods); -} - -// --------------------------------------------------------------------------- -void __fastcall InfoVmtInfo::AddInterface(String Value) { - if (!interfaces) - interfaces = new TStringList; - interfaces->Add(Value); -} - -// --------------------------------------------------------------------------- -PFIELDINFO __fastcall InfoVmtInfo::AddField(DWORD ProcAdr, int ProcOfs, BYTE Scope, int Offset, int Case, String Name, String Type) { - PFIELDINFO fInfo = 0; - - if (!fields) - fields = new TList; - if (!fields->Count) { - fInfo = new FIELDINFO; - fInfo->Scope = Scope; - fInfo->Offset = Offset; - fInfo->Case = Case; - fInfo->xrefs = 0; - fInfo->Name = Name; - fInfo->Type = Type; - fields->Add((void*)fInfo); - return fInfo; - } - - int F = 0, L = fields->Count - 1; - while (F < L) { - int M = (F + L) / 2; - fInfo = (PFIELDINFO)fields->Items[M]; - if (Offset <= fInfo->Offset) - L = M; - else - F = M + 1; - } - fInfo = (PFIELDINFO)fields->Items[L]; - if (fInfo->Offset != Offset) { - fInfo = new FIELDINFO; - fInfo->Scope = Scope; - fInfo->Offset = Offset; - fInfo->Case = Case; - fInfo->xrefs = 0; - fInfo->Name = Name; - fInfo->Type = Type; - fields->Add((void*)fInfo); - fields->Sort(FieldsCmpFunction); - } - else { - if (fInfo->Name == "") - fInfo->Name = Name; - if (fInfo->Type == "") - fInfo->Type = Type; - } - return fInfo; -} - -// --------------------------------------------------------------------------- -void __fastcall InfoVmtInfo::RemoveField(int Offset) { - PFIELDINFO fInfo; - - if (!fields || !fields->Count) - return; - int F = 0, L = fields->Count - 1; - while (F < L) { - int M = (F + L) / 2; - fInfo = (PFIELDINFO)fields->Items[M]; - if (Offset <= fInfo->Offset) - L = M; - else - F = M + 1; - } - - fInfo = (PFIELDINFO)fields->Items[L]; - if (fInfo->Offset == Offset) - fields->Delete(L); -} - -// --------------------------------------------------------------------------- -bool __fastcall InfoVmtInfo::AddMethod(bool Abstract, char Kind, int Id, DWORD Address, String Name) { - PMethodRec recM; - - if (!methods) - methods = new TList; - - for (int n = 0; n < methods->Count; n++) { - recM = (PMethodRec)methods->Items[n]; - if (Kind == 'A' || Kind == 'V') { - if (recM->kind == Kind && recM->id == Id) { - if (recM->name == "" && Name != "") - recM->name = Name; - return false; - } - } - else { - if (recM->kind == Kind && recM->address == Address) { - if (recM->name == "" && Name != "") - recM->name = Name; - return false; - } - } - } - - recM = new MethodRec; - recM->abstract = Abstract; - recM->kind = Kind; - recM->id = Id; - recM->address = Address; - recM->name = Name; - methods->Add((void*)recM); - return true; -} - -// --------------------------------------------------------------------------- -_fastcall InfoProcInfo::InfoProcInfo() { - flags = 0; - bpBase = 0; - retBytes = 0; - procSize = 0; - stackSize = 0; - args = 0; - locals = 0; -} - -// --------------------------------------------------------------------------- -__fastcall InfoProcInfo::~InfoProcInfo() { - CleanupList(args); - CleanupList(locals); -} - -// --------------------------------------------------------------------------- -PARGINFO __fastcall InfoProcInfo::AddArg(PARGINFO aInfo) { - return AddArg(aInfo->Tag, aInfo->Ndx, aInfo->Size, aInfo->Name, aInfo->TypeDef); -} - -// --------------------------------------------------------------------------- -PARGINFO __fastcall InfoProcInfo::AddArg(BYTE Tag, int Ofs, int Size, String Name, String TypeDef) { - PARGINFO argInfo; - if (!args) - args = new TList; - if (!args->Count) { - argInfo = new ARGINFO; - argInfo->Tag = Tag; - argInfo->Register = false; - argInfo->Ndx = Ofs; - argInfo->Size = Size; - argInfo->Name = Name; - argInfo->TypeDef = TypeDef; - args->Add((void*)argInfo); - return argInfo; - } - - int F = 0; - argInfo = (PARGINFO)args->Items[F]; - if (Ofs < argInfo->Ndx) { - argInfo = new ARGINFO; - argInfo->Tag = Tag; - argInfo->Register = false; - argInfo->Ndx = Ofs; - argInfo->Size = Size; - argInfo->Name = Name; - argInfo->TypeDef = TypeDef; - args->Insert(F, (void*)argInfo); - return argInfo; - } - int L = args->Count - 1; - argInfo = (PARGINFO)args->Items[L]; - if (Ofs > argInfo->Ndx) { - argInfo = new ARGINFO; - argInfo->Tag = Tag; - argInfo->Register = false; - argInfo->Ndx = Ofs; - argInfo->Size = Size; - argInfo->Name = Name; - argInfo->TypeDef = TypeDef; - args->Add((void*)argInfo); - return argInfo; - } - while (F < L) { - int M = (F + L) / 2; - argInfo = (PARGINFO)args->Items[M]; - if (Ofs <= argInfo->Ndx) - L = M; - else - F = M + 1; - } - argInfo = (PARGINFO)args->Items[L]; - if (argInfo->Ndx != Ofs) { - argInfo = new ARGINFO; - argInfo->Tag = Tag; - argInfo->Register = false; - argInfo->Ndx = Ofs; - argInfo->Size = Size; - argInfo->Name = Name; - argInfo->TypeDef = TypeDef; - args->Insert(L, (void*)argInfo); - return argInfo; - } - - if (argInfo->Name == "") - argInfo->Name = Name; - if (argInfo->TypeDef == "") - argInfo->TypeDef = TypeDef; - if (!argInfo->Tag) - argInfo->Tag = Tag; - return argInfo; -} - -// --------------------------------------------------------------------------- -String __fastcall InfoProcInfo::AddArgsFromDeclaration(char* Decl, int from, int callKind) { - bool fColon; - char *p, *pp, *cp, c, sc; - int ss, num; - ARGINFO argInfo; - char _Name[256]; - char _Type[256]; - char _Size[256]; - - p = strchr(Decl, '('); - if (p) { - p++; - pp = p; - num = 0; - fColon = false; - while (1) { - c = *pp; - if (c == ')') - break; - if (c == ':' && !fColon) { - *pp = ' '; - num++; - fColon = true; - } - if (c == ';') - fColon = false; - pp++; - } - if (num) { - ss = bpBase; - for (int arg = from; ; arg++) { - _Name[0] = _Type[0] = 0; - sc = ';'; - pp = strchr(p, sc); - if (!pp) { - sc = ')'; - pp = strchr(p, sc); - } - *pp = 0; - // Tag - argInfo.Tag = 0x21; - while (*p == ' ') - p++; - sscanf(p, "%s", _Name); - if (!stricmp(_Name, "var")) { - argInfo.Tag = 0x22; - p += strlen(_Name); - while (*p == ' ') - p++; - // Name - sscanf(p, "%s", _Name); - } - - // Insert by ZGL - else if (!stricmp(_Name, "const")) { - argInfo.Tag = 0x23; - p += strlen(_Name); - while (*p == ' ') - p++; - // Name - sscanf(p, "%s", _Name); - } - //////////////// - - else if (!stricmp(_Name, "val")) { - p += strlen(_Name); - while (*p == ' ') - p++; - // Name - sscanf(p, "%s", _Name); - } - p += strlen(_Name); - while (*p == ' ') - p++; - // Type - strcpy(_Type, p); - p += strlen(_Type); - while (*p == ' ') - p++; - argInfo.Size = 4; - cp = strchr(_Type, ':'); - if (cp) { - sscanf(cp + 1, "%d", &argInfo.Size); - *cp = 0; - } - if (callKind == 0) // fastcall - { - if (arg < 3 && argInfo.Size == 4) - argInfo.Ndx = arg; - else { - argInfo.Ndx = ss; - ss += argInfo.Size; - } - } - else { - argInfo.Ndx = ss; - ss += argInfo.Size; - } - if (_Name[0] == '?' && _Name[1] == 0) - argInfo.Name = ""; - else - argInfo.Name = String(_Name).Trim(); - - if (_Type[0] == '?' && _Type[1] == 0) - argInfo.TypeDef = ""; - else - argInfo.TypeDef = TrimTypeName(String(_Type)); - - AddArg(&argInfo); - *pp = ' '; - p = pp + 1; - if (sc == ')') - break; - } - } - } - else { - p = Decl; - } - p = strchr(p, ':'); - if (p) { - p++; - pp = strchr(p, ';'); - if (pp) { - *pp = 0; - strcpy(_Name, p); - *pp = ';'; - } - else - strcpy(_Name, p); - return String(_Name).Trim(); - } - return ""; -} - -// --------------------------------------------------------------------------- -PARGINFO __fastcall InfoProcInfo::GetArg(int n) { - if (args && n >= 0 && n < args->Count) - return (PARGINFO)args->Items[n]; - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall InfoProcInfo::DeleteArg(int n) { - if (args && n >= 0 && n < args->Count) - args->Delete(n); -} - -// --------------------------------------------------------------------------- -void __fastcall InfoProcInfo::DeleteArgs() { - if (args) { - for (int n = 0; n < args->Count; n++) - args->Delete(n); - args->Clear(); - } -} - -// --------------------------------------------------------------------------- -PLOCALINFO __fastcall InfoProcInfo::AddLocal(int Ofs, int Size, String Name, String TypeDef) { - PLOCALINFO locInfo; - - if (!locals) - locals = new TList; - if (!locals->Count) { - locInfo = new LOCALINFO; - locInfo->Ofs = Ofs; - locInfo->Size = Size; - locInfo->Name = Name; - locInfo->TypeDef = TypeDef; - locals->Add((void*)locInfo); - return locInfo; - } - - int F = 0; - locInfo = (PLOCALINFO)locals->Items[F]; - if (-Ofs < -locInfo->Ofs) { - locInfo = new LOCALINFO; - locInfo->Ofs = Ofs; - locInfo->Size = Size; - locInfo->Name = Name; - locInfo->TypeDef = TypeDef; - locals->Insert(F, (void*)locInfo); - return locInfo; - } - int L = locals->Count - 1; - locInfo = (PLOCALINFO)locals->Items[L]; - if (-Ofs > -locInfo->Ofs) { - locInfo = new LOCALINFO; - locInfo->Ofs = Ofs; - locInfo->Size = Size; - locInfo->Name = Name; - locInfo->TypeDef = TypeDef; - locals->Add((void*)locInfo); - return locInfo; - } - while (F < L) { - int M = (F + L) / 2; - locInfo = (PLOCALINFO)locals->Items[M]; - if (-Ofs <= -locInfo->Ofs) - L = M; - else - F = M + 1; - } - locInfo = (PLOCALINFO)locals->Items[L]; - if (locInfo->Ofs != Ofs) { - locInfo = new LOCALINFO; - locInfo->Ofs = Ofs; - locInfo->Size = Size; - locInfo->Name = Name; - locInfo->TypeDef = TypeDef; - locals->Insert(L, (void*)locInfo); - } - else { - if (Name != "") - locInfo->Name = Name; - if (TypeDef != "") - locInfo->TypeDef = TypeDef; - } - return locInfo; -} - -// --------------------------------------------------------------------------- -PLOCALINFO __fastcall InfoProcInfo::GetLocal(int Ofs) { - if (locals) { - for (int n = 0; n < locals->Count; n++) { - PLOCALINFO locInfo = (PLOCALINFO)locals->Items[n]; - if (locInfo->Ofs == Ofs) - return locInfo; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -PLOCALINFO __fastcall InfoProcInfo::GetLocal(String Name) { - if (locals) { - for (int n = 0; n < locals->Count; n++) { - PLOCALINFO locInfo = (PLOCALINFO)locals->Items[n]; - if (SameText(locInfo->Name, Name)) - return locInfo; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall InfoProcInfo::DeleteLocal(int n) { - if (locals && n >= 0 && n < locals->Count) - locals->Delete(n); -} - -// --------------------------------------------------------------------------- -void __fastcall InfoProcInfo::DeleteLocals() { - if (locals) { - for (int n = 0; n < locals->Count; n++) - locals->Delete(n); - locals->Clear(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall InfoProcInfo::SetLocalType(int Ofs, String TypeDef) { - PLOCALINFO locInfo = GetLocal(Ofs); - if (locInfo) { - String fname = locInfo->Name; - int pos = fname.Pos("."); - if (pos) - fname = fname.SubString(1, pos - 1); - locInfo->TypeDef = TypeDef; - int size; - if (TypeDef != "" && GetTypeKind(TypeDef, &size) == ikRecord) { - AnsiString recFileName = FMain_11011981->WrkDir + "\\types.idr"; - FILE* recFile = fopen(recFileName.c_str(), "rt"); - if (recFile) { - while (1) { - if (!fgets(StringBuf, 1024, recFile)) - break; - String str = String(StringBuf); - if (str.Pos(TypeDef + "=") == 1) { - while (1) { - if (!fgets(StringBuf, 1024, recFile)) - break; - str = String(StringBuf); - if (str.Pos("end;")) - break; - int pos2 = str.Pos("//"); - if (pos2) { - String ofs = str.SubString(pos2 + 2, str.Length()); - int pos1 = str.Pos(":"); - if (pos1) { - String name = str.SubString(1, pos1 - 1); - String type = str.SubString(pos1 + 1, pos2 - pos1 - 1); - AddLocal(StrToInt("$" + ofs) + Ofs, 1, fname + "." + name, type); - } - } - } - } - } - fclose(recFile); - } - while (1) { - // KB - WORD* uses = KnowledgeBase.GetTypeUses(AnsiString(TypeDef).c_str()); - int idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(TypeDef).c_str()); - if (uses) - delete[]uses; - - if (idx == -1) - break; - - idx = KnowledgeBase.TypeOffsets[idx].NamId; - MTypeInfo tInfo; - if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS, &tInfo)) { - if (tInfo.FieldsNum) { - char* p = tInfo.Fields; - for (int k = 0; k < tInfo.FieldsNum; k++) { - // Scope - p++; - int elofs = *((int*)p); - p += 4; - p += 4; // case - // Name - int len = *((WORD*)p); - p += 2; - String name = String((char*)p, len); - p += len + 1; - // Type - len = *((WORD*)p); - p += 2; - String type = TrimTypeName(String((char*)p, len)); - p += len + 1; - AddLocal(Ofs + elofs, 1, fname + "." + name, type); - } - break; - } - if (tInfo.Decl != "") { - TypeDef = tInfo.Decl; - } - } - } - } - } -} - -// --------------------------------------------------------------------------- -__fastcall InfoRec::InfoRec(int APos, BYTE AKind) { - counter = 0; - kind = AKind; - kbIdx = -1; - name = ""; - type = ""; - picode = 0; - xrefs = 0; - rsInfo = 0; - vmtInfo = 0; - procInfo = 0; - - if (kind == ikResString) - rsInfo = new InfoResStringInfo; - else if (kind == ikVMT) - vmtInfo = new InfoVmtInfo; - else if (kind >= ikRefine && kind <= ikFunc) - procInfo = new InfoProcInfo; - - if (APos >= 0) { - if (Infos[APos]) { - // as: if we here - memory leak then! - ++stat_InfosOverride; - } - Infos[APos] = this; - } -} - -// --------------------------------------------------------------------------- -__fastcall InfoRec::~InfoRec() { - if (picode) - delete picode; - - CleanupList(xrefs); - - if (kind == ikResString) { - delete rsInfo; - rsInfo = 0; - } - else if (kind == ikVMT) { - delete vmtInfo; - vmtInfo = 0; - } - else if (kind >= ikRefine && kind <= ikFunc) { - delete procInfo; - procInfo = 0; - } -} - -// --------------------------------------------------------------------------- -bool __fastcall InfoRec::HasName() { - return (name != ""); -} - -// --------------------------------------------------------------------------- -String __fastcall InfoRec::GetName() { - return name; -} - -// --------------------------------------------------------------------------- -int __fastcall InfoRec::GetNameLength() { - return name.Length(); -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::SetName(String AValue) { - CrtSection->Enter(); - name = AValue; - if (ExtractClassName(name) != "" && (kind >= ikRefine && kind <= ikFunc) && procInfo) - procInfo->flags |= PF_METHOD; - CrtSection->Leave(); -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::ConcatName(String AValue) { - name += AValue; -} - -// --------------------------------------------------------------------------- -bool __fastcall InfoRec::SameName(String AValue) { - return SameText(name, AValue); -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::AddXref(char Type, DWORD Adr, int Offset) { - PXrefRec recX; - - if (!xrefs) - xrefs = new TList; - if (!xrefs->Count) { - recX = new XrefRec; - recX->type = Type; - recX->adr = Adr; - recX->offset = Offset; - xrefs->Add((void*)recX); - return; - } - - int F = 0; - recX = (PXrefRec)xrefs->Items[F]; - if (Adr + Offset < recX->adr + recX->offset) { - recX = new XrefRec; - recX->type = Type; - recX->adr = Adr; - recX->offset = Offset; - xrefs->Insert(F, (void*)recX); - return; - } - int L = xrefs->Count - 1; - recX = (PXrefRec)xrefs->Items[L]; - if (Adr + Offset > recX->adr + recX->offset) { - recX = new XrefRec; - recX->type = Type; - recX->adr = Adr; - recX->offset = Offset; - xrefs->Add((void*)recX); - return; - } - while (F < L) { - int M = (F + L) / 2; - recX = (PXrefRec)xrefs->Items[M]; - if (Adr + Offset <= recX->adr + recX->offset) - L = M; - else - F = M + 1; - } - recX = (PXrefRec)xrefs->Items[L]; - if (recX->adr + recX->offset != Adr + Offset) { - recX = new XrefRec; - recX->type = Type; - recX->adr = Adr; - recX->offset = Offset; - xrefs->Insert(L, (void*)recX); - } -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::DeleteXref(DWORD Adr) { - for (int n = 0; n < xrefs->Count; n++) { - PXrefRec recX = (PXrefRec)xrefs->Items[n]; - if (Adr == recX->adr + recX->offset) { - xrefs->Delete(n); - break; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::ScanUpItemAndAddRef(int fromPos, DWORD itemAdr, char refType, DWORD refAdr) { - while (fromPos >= 0) { - fromPos--; - if (IsFlagSet(cfProcStart, fromPos)) - break; - if (IsFlagSet(cfInstruction, fromPos)) { - DISINFO _disInfo; - Disasm.Disassemble(Code + fromPos, (__int64)Pos2Adr(fromPos), &_disInfo, 0); - if (_disInfo.Immediate == itemAdr || _disInfo.Offset == itemAdr) { - AddXref(refType, refAdr, Pos2Adr(fromPos) - refAdr); - break; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::Save(TStream* outs) { - int m, xm, num, xnum, len; - - // kbIdx - outs->Write(&kbIdx, sizeof(kbIdx)); - // name - len = name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(name.c_str(), len); - // type - len = type.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(type.c_str(), len); - // picode - outs->Write(&picode, sizeof(picode)); - if (picode) { - // Op - outs->Write(&picode->Op, sizeof(picode->Op)); - // Ofs - if (picode->Op == OP_CALL) - outs->Write(&picode->Ofs.Address, sizeof(picode->Ofs.Address)); - else - outs->Write(&picode->Ofs.Offset, sizeof(picode->Ofs.Offset)); - // Name - len = picode->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(picode->Name.c_str(), len); - } - // xrefs - if (xrefs && xrefs->Count) - num = xrefs->Count; - else - num = 0; - outs->Write(&num, sizeof(num)); - for (m = 0; m < num; m++) { - PXrefRec recX = (PXrefRec)xrefs->Items[m]; - // type - outs->Write(&recX->type, sizeof(recX->type)); - // adr - outs->Write(&recX->adr, sizeof(recX->adr)); - // offset - outs->Write(&recX->offset, sizeof(recX->offset)); - } - if (kind == ikResString) { - // value - len = rsInfo->value.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(rsInfo->value.c_str(), len); - } - else if (kind == ikVMT) { - // interfaces - if (vmtInfo->interfaces && vmtInfo->interfaces->Count) - num = vmtInfo->interfaces->Count; - else - num = 0; - outs->Write(&num, sizeof(num)); - for (m = 0; m < num; m++) { - len = vmtInfo->interfaces->Strings[m].Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(vmtInfo->interfaces->Strings[m].c_str(), len); - } - // fields - if (vmtInfo->fields && vmtInfo->fields->Count) - num = vmtInfo->fields->Count; - else - num = 0; - outs->Write(&num, sizeof(num)); - for (m = 0; m < num; m++) { - PFIELDINFO fInfo = (PFIELDINFO)vmtInfo->fields->Items[m]; - // Scope - outs->Write(&fInfo->Scope, sizeof(fInfo->Scope)); - // Offset - outs->Write(&fInfo->Offset, sizeof(fInfo->Offset)); - // Case - outs->Write(&fInfo->Case, sizeof(fInfo->Case)); - // Name - len = fInfo->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(fInfo->Name.c_str(), len); - // Type - len = fInfo->Type.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(fInfo->Type.c_str(), len); - // xrefs - if (fInfo->xrefs && fInfo->xrefs->Count) - xnum = fInfo->xrefs->Count; - else - xnum = 0; - outs->Write(&xnum, sizeof(xnum)); - for (xm = 0; xm < xnum; xm++) { - PXrefRec recX = (PXrefRec)fInfo->xrefs->Items[xm]; - // type - outs->Write(&recX->type, sizeof(recX->type)); - // adr - outs->Write(&recX->adr, sizeof(recX->adr)); - // offset - outs->Write(&recX->offset, sizeof(recX->offset)); - } - } - // methods - if (vmtInfo->methods && vmtInfo->methods->Count) - num = vmtInfo->methods->Count; - else - num = 0; - outs->Write(&num, sizeof(num)); - for (m = 0; m < num; m++) { - PMethodRec recM = (PMethodRec)vmtInfo->methods->Items[m]; - outs->Write(&recM->abstract, sizeof(recM->abstract)); - outs->Write(&recM->kind, sizeof(recM->kind)); - outs->Write(&recM->id, sizeof(recM->id)); - outs->Write(&recM->address, sizeof(recM->address)); - len = recM->name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(recM->name.c_str(), len); - } - } - else if (kind >= ikRefine && kind <= ikFunc) { - // flags - outs->Write(&procInfo->flags, sizeof(procInfo->flags)); - // bpBase - outs->Write(&procInfo->bpBase, sizeof(procInfo->bpBase)); - // retBytes - outs->Write(&procInfo->retBytes, sizeof(procInfo->retBytes)); - // procSize - outs->Write(&procInfo->procSize, sizeof(procInfo->procSize)); - // stackSize - outs->Write(&procInfo->stackSize, sizeof(procInfo->stackSize)); - // args - if (procInfo->args && procInfo->args->Count) - num = procInfo->args->Count; - else - num = 0; - outs->Write(&num, sizeof(num)); - for (m = 0; m < num; m++) { - PARGINFO argInfo = (PARGINFO)procInfo->args->Items[m]; - // Tag - outs->Write(&argInfo->Tag, sizeof(argInfo->Tag)); - // Register - outs->Write(&argInfo->Register, sizeof(argInfo->Register)); - // Ndx - outs->Write(&argInfo->Ndx, sizeof(argInfo->Ndx)); - // Size - outs->Write(&argInfo->Size, sizeof(argInfo->Size)); - // Name - len = argInfo->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(argInfo->Name.c_str(), len); - // TypeDef - len = argInfo->TypeDef.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(argInfo->TypeDef.c_str(), len); - } - // locals - if (procInfo->locals && procInfo->locals->Count) - num = procInfo->locals->Count; - else - num = 0; - outs->Write(&num, sizeof(num)); - for (m = 0; m < num; m++) { - PLOCALINFO locInfo = (PLOCALINFO)procInfo->locals->Items[m]; - // Ofs - outs->Write(&locInfo->Ofs, sizeof(locInfo->Ofs)); - // Size - outs->Write(&locInfo->Size, sizeof(locInfo->Size)); - // Name - len = locInfo->Name.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(locInfo->Name.c_str(), len); - // TypeDef - len = locInfo->TypeDef.Length(); - if (len > MaxBufLen) - MaxBufLen = len; - outs->Write(&len, sizeof(len)); - outs->Write(locInfo->TypeDef.c_str(), len); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall InfoRec::Load(TStream* ins, char* buf) { - int m, xm, num, xnum, len, xrefAdr, pxrefAdr; - XrefRec recX1; - - // kbIdx - ins->Read(&kbIdx, sizeof(kbIdx)); - // name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - name = String(buf, len); - // type - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - type = String(buf, len); - // picode - ins->Read(&picode, sizeof(picode)); - if (picode) { - picode = new PICODE; - // Op - ins->Read(&picode->Op, sizeof(picode->Op)); - // Ofs - if (picode->Op == OP_CALL) - ins->Read(&picode->Ofs.Address, sizeof(picode->Ofs.Address)); - else - ins->Read(&picode->Ofs.Offset, sizeof(picode->Ofs.Offset)); - // Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - picode->Name = String(buf, len); - } - // xrefs - ins->Read(&num, sizeof(num)); - if (num) - xrefs = new TList; - pxrefAdr = 0; - for (m = 0; m < num; m++) { - // type - ins->Read(&recX1.type, sizeof(recX1.type)); - // adr - ins->Read(&recX1.adr, sizeof(recX1.adr)); - // offset - ins->Read(&recX1.offset, sizeof(recX1.offset)); - xrefAdr = recX1.adr + recX1.offset; - if (!pxrefAdr || pxrefAdr != xrefAdr) // clear duplicates - { - PXrefRec recX = new XrefRec; - recX->type = recX1.type; - recX->adr = recX1.adr; - recX->offset = recX1.offset; - xrefs->Add((void*)recX); - pxrefAdr = xrefAdr; - } - } - if (kind == ikResString) { - // value - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - rsInfo->value = String(buf, len); - } - else if (kind == ikVMT) { - // interfaces - ins->Read(&num, sizeof(num)); - if (num) - vmtInfo->interfaces = new TStringList; - for (m = 0; m < num; m++) { - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - vmtInfo->interfaces->Add(String(buf, len)); - } - // fields - ins->Read(&num, sizeof(num)); - if (num) - vmtInfo->fields = new TList; - for (m = 0; m < num; m++) { - PFIELDINFO fInfo = new FIELDINFO; - // Scope - ins->Read(&fInfo->Scope, sizeof(fInfo->Scope)); - // Offset - ins->Read(&fInfo->Offset, sizeof(fInfo->Offset)); - // Case - ins->Read(&fInfo->Case, sizeof(fInfo->Case)); - // Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - fInfo->Name = String(buf, len); - // Type - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - fInfo->Type = String(buf, len); - // xrefs - ins->Read(&xnum, sizeof(xnum)); - if (xnum) - fInfo->xrefs = new TList; - else - fInfo->xrefs = 0; - for (xm = 0; xm < xnum; xm++) { - PXrefRec recX = new XrefRec; - // type - ins->Read(&recX->type, sizeof(recX->type)); - // adr - ins->Read(&recX->adr, sizeof(recX->adr)); - // offset - ins->Read(&recX->offset, sizeof(recX->offset)); - fInfo->xrefs->Add((void*)recX); - } - vmtInfo->fields->Add((void*)fInfo); - } - // methods - ins->Read(&num, sizeof(num)); - if (num) - vmtInfo->methods = new TList; - for (m = 0; m < num; m++) { - PMethodRec recM = new MethodRec; - ins->Read(&recM->abstract, sizeof(recM->abstract)); - ins->Read(&recM->kind, sizeof(recM->kind)); - ins->Read(&recM->id, sizeof(recM->id)); - ins->Read(&recM->address, sizeof(recM->address)); - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - recM->name = String(buf, len); - vmtInfo->methods->Add((void*)recM); - } - } - else if (kind >= ikRefine && kind <= ikFunc) { - // flags - ins->Read(&procInfo->flags, sizeof(procInfo->flags)); - // bpBase - ins->Read(&procInfo->bpBase, sizeof(procInfo->bpBase)); - // retBytes - ins->Read(&procInfo->retBytes, sizeof(procInfo->retBytes)); - // procSize - ins->Read(&procInfo->procSize, sizeof(procInfo->procSize)); - // stackSize - ins->Read(&procInfo->stackSize, sizeof(procInfo->stackSize)); - // args - ins->Read(&num, sizeof(num)); - if (num) - procInfo->args = new TList; - for (m = 0; m < num; m++) { - PARGINFO argInfo = new ARGINFO; - // Tag - ins->Read(&argInfo->Tag, sizeof(argInfo->Tag)); - // Register - ins->Read(&argInfo->Register, sizeof(argInfo->Register)); - // Ndx - ins->Read(&argInfo->Ndx, sizeof(argInfo->Ndx)); - // Size - ins->Read(&argInfo->Size, sizeof(argInfo->Size)); - // Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - argInfo->Name = String(buf, len); - // TypeDef - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - argInfo->TypeDef = TrimTypeName(String(buf, len)); - procInfo->args->Add((void*)argInfo); - } - // locals - ins->Read(&num, sizeof(num)); - if (num) - procInfo->locals = new TList; - for (m = 0; m < num; m++) { - PLOCALINFO locInfo = new LOCALINFO; - // Ofs - ins->Read(&locInfo->Ofs, sizeof(locInfo->Ofs)); - // Size - ins->Read(&locInfo->Size, sizeof(locInfo->Size)); - // Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - locInfo->Name = String(buf, len); - // TypeDef - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - locInfo->TypeDef = TrimTypeName(String(buf, len)); - procInfo->locals->Add((void*)locInfo); - } - } -} - -// --------------------------------------------------------------------------- -/* - void __fastcall InfoRec::Skip(TStream* ins, char* buf, BYTE asKind) - { - DWORD dummy; - int m, xm, len, num, xnum; - PICODE picode; - XrefRec recX; - FIELDINFO fInfo; - MethodRec recM; - ARGINFO argInfo; - LOCALINFO locInfo; - - //kbIdx - ins->Read(&dummy, sizeof(kbIdx)); - //name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - //type - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - //picode - ins->Read(&dummy, sizeof(dummy)); - if (dummy) - { - //Op - ins->Read(&picode.Op, sizeof(picode.Op)); - //Ofs - if (dummy == OP_CALL) - ins->Read(&picode.Ofs.Address, sizeof(picode.Ofs.Address)); - else - ins->Read(&picode.Ofs.Offset, sizeof(picode.Ofs.Offset)); - //Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - } - //xrefs - ins->Read(&num, sizeof(num)); - for (m = 0; m < num; m++) - { - //type - ins->Read(&recX.type, sizeof(recX.type)); - //adr - ins->Read(&recX.adr, sizeof(recX.adr)); - //offset - ins->Read(&recX.offset, sizeof(recX.offset)); - } - if (asKind == ikResString) - { - //value - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - } - else if (asKind == ikVMT) - { - //interfaces - ins->Read(&num, sizeof(num)); - for (m = 0; m < num; m++) - { - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - } - //fields - ins->Read(&num, sizeof(num)); - for (m = 0; m < num; m++) - { - //Scope - ins->Read(&fInfo.Scope, sizeof(fInfo.Scope)); - //Offset - ins->Read(&fInfo.Offset, sizeof(fInfo.Offset)); - //Case - ins->Read(&fInfo.Case, sizeof(fInfo.Case)); - //Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - //Type - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - //xrefs - ins->Read(&xnum, sizeof(xnum)); - for (xm = 0; xm < xnum; xm++) - { - //type - ins->Read(&recX.type, sizeof(recX.type)); - //adr - ins->Read(&recX.adr, sizeof(recX.adr)); - //offset - ins->Read(&recX.offset, sizeof(recX.offset)); - } - } - //methods - ins->Read(&num, sizeof(num)); - for (m = 0; m < num; m++) - { - ins->Read(&recM.abstract, sizeof(recM.abstract)); - ins->Read(&recM.kind, sizeof(recM.kind)); - ins->Read(&recM.id, sizeof(recM.id)); - ins->Read(&recM.address, sizeof(recM.address)); - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - } - } - else if (asKind >= ikRefine && asKind <= ikFunc) - { - //flags - ins->Read(&dummy, sizeof(info.procInfo->flags)); - //bpBase - ins->Read(&dummy, sizeof(info.procInfo->bpBase)); - //retBytes - ins->Read(&dummy, sizeof(info.procInfo->retBytes)); - //procSize - ins->Read(&dummy, sizeof(info.procInfo->procSize)); - //stackSize - ins->Read(&dummy, sizeof(info.procInfo->stackSize)); - //args - ins->Read(&num, sizeof(num)); - for (m = 0; m < num; m++) - { - //Tag - ins->Read(&argInfo.Tag, sizeof(argInfo.Tag)); - //Register - ins->Read(&argInfo.Register, sizeof(argInfo.Register)); - //Ndx - ins->Read(&argInfo.Ndx, sizeof(argInfo.Ndx)); - //Size - ins->Read(&argInfo.Size, sizeof(argInfo.Size)); - //Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - //TypeDef - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - } - //locals - ins->Read(&num, sizeof(num)); - for (m = 0; m < num; m++) - { - //Ofs - ins->Read(&locInfo.Ofs, sizeof(locInfo.Ofs)); - //Size - ins->Read(&locInfo.Size, sizeof(locInfo.Size)); - //Name - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - //TypeDef - ins->Read(&len, sizeof(len)); - ins->Read(buf, len); - } - } - } - */ -// --------------------------------------------------------------------------- -String __fastcall InfoRec::MakePrototype(int adr, bool showKind, bool showTail, bool multiline, bool fullName, bool allArgs) { - BYTE callKind; - int n, num, argsNum, firstArg; - PARGINFO argInfo; - String result = ""; - - if (showKind) { - if (kind == ikConstructor) - result += "constructor"; - else if (kind == ikDestructor) - result += "destructor"; - else if (kind == ikFunc) - result += "function"; - else if (kind == ikProc) - result += "procedure"; - - if (result != "") - result += " "; - } - - if (name != "") { - if (!fullName) - result += ExtractProcName(name); - else - result += name; - } - else - result += GetDefaultProcName(adr); - - num = argsNum = (procInfo->args) ? procInfo->args->Count : 0; - firstArg = 0; - - if (num && !allArgs) { - if (kind == ikConstructor || kind == ikDestructor) { - firstArg = 2; - num -= 2; - } - else if (procInfo->flags & PF_ALLMETHODS) { - firstArg = 1; - num--; - } - } - if (num) { - result += "("; - if (multiline) - result += "\r\n"; - - for (n = firstArg; n < argsNum; n++) { - if (n != firstArg) { - result += ";"; - if (multiline) - result += "\r\n"; - else - result += " "; - } - - argInfo = (PARGINFO)procInfo->args->Items[n]; - if (argInfo->Tag == 0x22) - result += "var "; - - else if (argInfo->Tag == 0x23) - result += "const "; // Add by ZGL - - if (argInfo->Name != "") - result += argInfo->Name; - else - result += "?"; - result += ":"; - if (argInfo->TypeDef != "") - result += argInfo->TypeDef; - else - result += "?"; - } - - if (multiline) - result += "\r\n"; - result += ")"; - } - - if (kind == ikFunc) { - result += ":"; - if (type != "") - result += TrimTypeName(type); - else - result += "?"; - } - result += ";"; - callKind = procInfo->flags & 7; - switch (callKind) { - case 1: - result += " cdecl;"; - break; - case 2: - result += " pascal;"; - break; - case 3: - result += " stdcall;"; - break; - case 4: - result += " safecall;"; - break; - } - String argres = ""; - // fastcall - if (!callKind) // (!IsFlagSet(cfImport, Adr2Pos(Adr))) - { - for (n = 0; n < argsNum; n++) { - argInfo = (PARGINFO)procInfo->args->Items[n]; - // if (!callKind) - // { - if (argInfo->Ndx == 0) - argres += "A"; - else if (argInfo->Ndx == 1) - argres += "D"; - else if (argInfo->Ndx == 2) - argres += "C"; - // } - } - } - if (showTail) { - if (argres != "") - result += " in" + argres; - // output registers - // if (info.procInfo->flags & PF_OUTEAX) result += " out"; - - if (procInfo->retBytes) - result += " RET" + Val2Str0(procInfo->retBytes); - - if (procInfo->flags & PF_ARGSIZEG) - result += "+"; - if (procInfo->flags & PF_ARGSIZEL) - result += "-"; - } - return result; -} - -// --------------------------------------------------------------------------- -String __fastcall InfoRec::MakeDelphiPrototype(int Adr, PMethodRec recM) { - bool abstract = false; - BYTE callKind; - int n, num, argsNum, firstArg, len = 0; - PARGINFO argInfo; - - if (kind == ikConstructor) - len = sprintf(StringBuf, "constructor"); - else if (kind == ikDestructor) - len = sprintf(StringBuf, "destructor"); - else if (kind == ikFunc) - len = sprintf(StringBuf, "function"); - else if (kind == ikProc) - len = sprintf(StringBuf, "procedure"); - - if (len > 0) - len += sprintf(StringBuf + len, " "); - - if (SameText(name, "@AbstractError")) - abstract = true; - - if (name != "") { - if (!abstract) - len += sprintf(StringBuf + len, "%s", ExtractProcName(name).c_str()); - else if (recM->name != "") - len += sprintf(StringBuf + len, "%s", ExtractProcName(recM->name).c_str()); - else - len += sprintf(StringBuf + len, "v%X", recM->id); - } - else - len += sprintf(StringBuf + len, "v%X", recM->id); - - num = argsNum = (procInfo->args) ? procInfo->args->Count : 0; - firstArg = 0; - - if (num) { - if (procInfo->flags & PF_ALLMETHODS) { - firstArg = 1; - num--; - if (kind == ikConstructor || kind == ikDestructor) { - firstArg++; - num--; - } - } - if (num) { - len += sprintf(StringBuf + len, "("); - - callKind = procInfo->flags & 7; - for (n = firstArg; n < argsNum; n++) { - if (n != firstArg) - len += sprintf(StringBuf + len, "; "); - - argInfo = (PARGINFO)procInfo->args->Items[n]; - if (argInfo->Tag == 0x22) - len += sprintf(StringBuf + len, "var "); - - else if (argInfo->Tag == 0x23) - len += sprintf(StringBuf + len, "const "); // Add by ZGL - - if (argInfo->Name != "") - len += sprintf(StringBuf + len, "%s", argInfo->Name.c_str()); - else - len += sprintf(StringBuf + len, "?"); - len += sprintf(StringBuf + len, ":"); - if (argInfo->TypeDef != "") - len += sprintf(StringBuf + len, "%s", argInfo->TypeDef.c_str()); - else - len += sprintf(StringBuf + len, "?"); - } - len += sprintf(StringBuf + len, ")"); - } - } - - if (kind == ikFunc) { - len += sprintf(StringBuf + len, ":"); - if (type != "") - len += sprintf(StringBuf + len, "%s", TrimTypeName(type).c_str()); - else - len += sprintf(StringBuf + len, "?"); - } - len += sprintf(StringBuf + len, "; virtual;"); - - if (abstract) - len += sprintf(StringBuf + len, " abstract;"); - else { - switch (callKind) { - case 1: - len += sprintf(StringBuf + len, " cdecl;"); - break; - case 2: - len += sprintf(StringBuf + len, " pascal;"); - break; - case 3: - len += sprintf(StringBuf + len, " stdcall;"); - break; - case 4: - len += sprintf(StringBuf + len, " safecall;"); - break; - } - } - return String(StringBuf, len); -} - -// --------------------------------------------------------------------------- -String __fastcall InfoRec::MakeMultilinePrototype(int Adr, int* ArgsBytes, String MethodType) { - BYTE callKind; - int n, num, argsNum, firstArg, argsBytes = 0; - PARGINFO argInfo; - String result; - - if (name != "") - result = name; - else - result = GetDefaultProcName(Adr); - - num = argsNum = (procInfo->args) ? procInfo->args->Count : 0; - firstArg = 0; - - if (kind == ikConstructor || kind == ikDestructor) { - firstArg = 2; - num -= 2; - } - else if (procInfo->flags & PF_ALLMETHODS) { - if (!num) { - argInfo = new ARGINFO; - argInfo->Tag = 0x21; - argInfo->Ndx = 0; - argInfo->Size = 4; - argInfo->Name = "Self"; - argInfo->TypeDef = MethodType; - procInfo->AddArg(argInfo); - } - else { - if (MethodType != "") { - argInfo = (PARGINFO)procInfo->args->Items[0]; - argInfo->Name = "Self"; - argInfo->TypeDef = MethodType; - procInfo->args->Items[0] = argInfo; - } - num--; - } - firstArg = 1; - } - - if (num > 0) - result += "(\r\n"; - callKind = procInfo->flags & 7; - for (n = firstArg; n < argsNum; n++) { - if (n != firstArg) - result += ";\r\n"; - - argInfo = (PARGINFO)procInfo->args->Items[n]; - // var - if (argInfo->Tag == 0x22) - result += "var "; - - else if (argInfo->Tag == 0x23) - result += "const "; // Add by ZGL - - // name - if (argInfo->Name != "") - result += argInfo->Name; - else - result += "?"; - // type - result += ":"; - if (argInfo->TypeDef != "") - result += argInfo->TypeDef; - else - result += "?"; - // size - if (argInfo->Size > 4) - result += ":" + String(argInfo->Size); - - if (argInfo->Ndx > 2) - argsBytes += argInfo->Size; - } - if (num > 0) - result += "\r\n)"; - - if (kind == ikFunc) { - result += ":"; - if (type != "") - result += TrimTypeName(type); - else - result += "?"; - } - result += ";"; - *ArgsBytes = argsBytes; - return result; -} - -// --------------------------------------------------------------------------- -String __fastcall InfoRec::MakeMapName(int Adr) { - String result; - if (name != "") - result = name; - else - result = GetDefaultProcName(Adr); - - return result; -} - -// --------------------------------------------------------------------------- -bool __fastcall InfoRec::MakeArgsManually() { - String _sname; - - // if (info.procInfo->flags & PF_KBPROTO) return true; - // Some procedures not begin with '@' - // function QueryInterface(Self:Pointer; IID:TGUID; var Obj:Pointer); - if (name.Pos(".QueryInterface")) { - kind = ikFunc; - type = "HRESULT"; - procInfo->flags &= 0xFFFFFFF8; - procInfo->flags |= 3; // stdcall - procInfo->AddArg(0x21, 8, 4, "Self", ""); - procInfo->AddArg(0x23, 12, 4, "IID", "TGUID"); // Midify by ZGL - procInfo->AddArg(0x22, 16, 4, "Obj", "Pointer"); - return true; - } - // function _AddRef(Self:Pointer):Integer; - // function _Release(Self:Pointer):Integer; - if (name.Pos("._AddRef") || name.Pos("._Release")) { - kind = ikFunc; - type = "Integer"; - procInfo->flags &= 0xFFFFFFF8; - procInfo->flags |= 3; // stdcall - procInfo->AddArg(0x21, 8, 4, "Self", ""); - return true; - } - // procedure DynArrayClear(var arr:Pointer; typeInfo:PDynArrayTypeInfo); - if (SameText(name, "DynArrayClear")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "arr", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "typeInfo", "PDynArrayTypeInfo"); - return true; - } - // procedure DynArraySetLength(var arr:Pointer; typeInfo:PDynArrayTypeInfo; dimCnt:Longint; lenVec:PLongint); - if (SameText(name, "DynArraySetLength")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "arr", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "typeInfo", "PDynArrayTypeInfo"); - procInfo->AddArg(0x21, 2, 4, "dimCnt", "Longint"); - procInfo->AddArg(0x21, 8, 4, "lenVec", "PLongint"); - return true; - } - - if (name[1] != '@') - return false; - - // Strings - if (name[2] == 'L') - _sname = "AnsiString"; - else if (name[2] == 'W') - _sname = "WideString"; - else if (name[2] == 'U') - _sname = "UnicodeString"; - else - _sname = "?"; - - if (_sname != "?") { - // @LStrClr, @WStrClr, @UStrClr - if (SameText(&name[3], "StrClr")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "S", _sname); - return true; - } - // @LStrArrayClr, @WStrArrayClr, @UStrArrayClr - if (SameText(&name[3], "StrArrayClr")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "StrArray", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "Count", "Integer"); - return true; - } - // @LStrAsg, @WStrAsg, @UStrAsg - if (SameText(&name[3], "StrAsg")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", _sname); - return true; - } - // @LStrLAsg, @WStrLAsg, @UStrLAsg - if (SameText(&name[3], "StrLAsg")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x23, 1, 4, "Source", _sname); // Modify by ZGL - return true; - } - // @LStrFromPCharLen, @WStrFromPCharLen, @UStrFromPCharLen - if (SameText(&name[3], "StrFromPCharLen")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "PAnsiChar"); - procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); - return true; - } - // @LStrFromPWCharLen, @WStrFromPWCharLen, @UStrFromPWCharLen - if (SameText(&name[3], "StrFromPWCharLen")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "PWideChar"); - procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); - return true; - } - // @LStrFromChar, @WStrFromChar, @UStrFromChar - if (SameText(&name[3], "StrFromChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "AnsiChar"); - return true; - } - // @LStrFromWChar, @WStrFromWChar, @UStrFromWChar - if (SameText(&name[3], "StrFromWChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "WideChar"); - return true; - } - // @LStrFromPChar, @WStrFromPChar, @UStrFromPChar - if (SameText(&name[3], "StrFromPChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "PAnsiChar"); - return true; - } - // @LStrFromPWChar, @WStrFromPWChar, @UStrFromPWChar - if (SameText(&name[3], "StrFromPWChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "PWideChar"); - return true; - } - // @LStrFromString, @WStrFromString, @UStrFromString - if (SameText(&name[3], "StrFromString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x23, 1, 4, "Source", "ShortString"); // Modify by ZGL - return true; - } - // @LStrFromArray, @WStrFromArray, @UStrFromArray - if (SameText(&name[3], "StrFromArray")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "PAnsiChar"); - procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); - return true; - } - // @LStrFromWArray, @WStrFromWArray, @UStrFromWArray - if (SameText(&name[3], "StrFromWArray")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", "PWideChar"); - procInfo->AddArg(0x21, 2, 4, "Length", "Integer"); - return 1; - } - // @LStrFromWStr, @UStrFromWStr - if (SameText(&name[3], "StrFromWStr")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x23, 1, 4, "Source", "WideString"); // Modify by ZGL - return true; - } - // @LStrToString, @WStrToString, @UStrToString - if (SameText(&name[3], "StrToString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", "ShortString"); - procInfo->AddArg(0x23, 1, 4, "Source", _sname); // Modify by ZGL - procInfo->AddArg(0x21, 2, 4, "MaxLen", "Integer"); - return true; - } - // @LStrLen, @WStrLen, @UStrLen - if (SameText(&name[3], "StrLen")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x21, 0, 4, "S", _sname); - return true; - } - // @LStrCat, @WStrCat, @UStrCat - if (SameText(&name[3], "StrCat")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", _sname); - return true; - } - // @LStrCat3, @WStrCat3, @UStrCat3 - if (SameText(&name[3], "StrCat3")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source1", _sname); - procInfo->AddArg(0x21, 2, 4, "Source2", _sname); - return true; - } - // @LStrCatN, @WStrCatN, @UStrCatN - if (SameText(&name[3], "StrCatN")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "ArgCnt", "Integer"); - return true; - } - // @LStrCmp, @WStrCmp, @UStrCmp - if (SameText(&name[3], "StrCmp")) // return Flags - { - kind = ikFunc; - procInfo->AddArg(0x21, 0, 4, "Left", _sname); - procInfo->AddArg(0x21, 1, 4, "Right", _sname); - return true; - } - // @LStrAddRef, @WStrAddRef, @UStrAddRef - if (SameText(&name[3], "StrAddRef")) { - kind = ikFunc; - type = "Pointer"; - procInfo->AddArg(0x22, 0, 4, "S", _sname); - return true; - } - // @LStrToPChar, @WStrToPChar, @UStrToPChar - if (SameText(&name[3], "StrToPChar")) { - kind = ikFunc; - type = "PChar"; - procInfo->AddArg(0x21, 0, 4, "S", _sname); - return true; - } - // @LStrCopy, @WStrCopy, @UStrCopy - if (SameText(&name[3], "StrCopy")) { - kind = ikFunc; - type = _sname; - procInfo->AddArg(0x23, 0, 4, "S", _sname); // Modify by ZGL - procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); - procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); - return true; - } - // @LStrDelete, @WStrDelete, @UStrDelete - if (SameText(&name[3], "StrDelete")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "S", _sname); - procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); - procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); - return true; - } - // @LStrInsert, @WStrInsert, @UStrInsert - if (SameText(&name[3], "StrInsert")) { - kind = ikProc; - procInfo->AddArg(0x23, 0, 4, "Source", _sname); // Modify by ZGL - procInfo->AddArg(0x22, 1, 4, "S", _sname); - procInfo->AddArg(0x21, 2, 4, "Index", "Integer"); - return true; - } - // @LStrPos, @WStrPos, @UStrPos - if (SameText(&name[3], "StrPos")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x23, 0, 4, "Substr", _sname); // Modify by ZGL - procInfo->AddArg(0x23, 1, 4, "S", _sname); // Modify by ZGL - return true; - } - // @LStrSetLength, @WStrSetLength, @UStrSetLength - if (SameText(&name[3], "StrSetLength")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "S", _sname); - procInfo->AddArg(0x21, 1, 4, "NewLen", "Integer"); - return true; - } - // @LStrOfChar, @WStrOfChar, @UStrOfChar - if (SameText(&name[3], "StrOfChar")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 1, "C", "Char"); - procInfo->AddArg(0x21, 1, 4, "Count", "Integer"); - procInfo->AddArg(0x22, 2, 4, "Result", _sname); - return 1; - } - // @WStrToPWChar, @UStrToPWChar - if (SameText(&name[3], "StrToPWChar")) { - kind = ikFunc; - type = "PWideChar"; - procInfo->AddArg(0x21, 0, 4, "S", _sname); - return true; - } - // @WStrFromLStr, @UStrFromLStr - if (SameText(&name[3], "StrFromLStr")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", _sname); - procInfo->AddArg(0x23, 1, 4, "Source", "AnsiString"); // Modify by ZGL - return true; - } - // @WStrOfWChar - if (SameText(&name[3], "StrOfWChar")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "C", "WideChar"); - procInfo->AddArg(0x21, 1, 4, "Count", "Integer"); - procInfo->AddArg(0x22, 2, 4, "Result", _sname); - return true; - } - // @UStrEqual - if (SameText(&name[3], "StrEqual")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Left", _sname); - procInfo->AddArg(0x21, 1, 4, "Right", _sname); - return true; - } - } - // ShortStrings-------------------------------------------------------------- - _sname = "ShortString"; - // @Copy - if (SameText(name, "@Copy")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "S", _sname); - procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); - procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); - procInfo->AddArg(0x21, 8, 4, "Result", _sname); - return true; - } - // @Delete - if (SameText(name, "@Delete")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "S", _sname); - procInfo->AddArg(0x21, 1, 4, "Index", "Integer"); - procInfo->AddArg(0x21, 2, 4, "Count", "Integer"); - return true; - } - // @Insert - if (SameText(name, "@Insert")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Source", _sname); - procInfo->AddArg(0x22, 1, 4, "Dest", "ShortString"); - procInfo->AddArg(0x21, 2, 4, "Index", "Integer"); - return true; - } - // @Pos - if (SameText(name, "@Pos")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x21, 0, 4, "Substr", _sname); - procInfo->AddArg(0x21, 1, 4, "S", _sname); - return true; - } - _sname = "PShortString"; - // @SetLength - if (SameText(name, "@SetLength")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "S", _sname); - procInfo->AddArg(0x21, 1, 4, "NewLength", "Byte"); - return true; - } - // @SetString - if (SameText(name, "@SetString")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "S", _sname); - procInfo->AddArg(0x21, 1, 4, "Buffer", "PChar"); - procInfo->AddArg(0x21, 2, 4, "Length", "Byte"); - return true; - } - // @PStrCat - if (SameText(name, "@PStrCat")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", _sname); - return true; - } - // @PStrNCat - if (SameText(name, "@PStrNCat")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", _sname); - procInfo->AddArg(0x21, 2, 4, "MaxLen", "Byte"); - return true; - } - // @PStrCpy - if (SameText(name, "@PStrCpy")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", _sname); - return true; - } - // @PStrNCpy - if (SameText(name, "@PStrNCpy")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Dest", _sname); - procInfo->AddArg(0x21, 1, 4, "Source", _sname); - procInfo->AddArg(0x21, 2, 4, "MaxLen", "Byte"); - return true; - } - // @AStrCmp - if (SameText(name, "@AStrCmp")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "S1", _sname); - procInfo->AddArg(0x21, 1, 4, "S2", _sname); - procInfo->AddArg(0x21, 2, 4, "Bytes", "Integer"); - return true; - } - // @PStrCmp - if (SameText(name, "@PStrCmp")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "S1", _sname); - procInfo->AddArg(0x21, 1, 4, "S2", _sname); - return true; - } - // @Str0Long - if (SameText(name, "@Str0Long")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Val", "Longint"); - procInfo->AddArg(0x21, 1, 4, "S", _sname); - return true; - } - // @StrLong - if (SameText(name, "@StrLong")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Val", "Integer"); - procInfo->AddArg(0x21, 1, 4, "Width", "Integer"); - procInfo->AddArg(0x21, 2, 4, "S", _sname); - return true; - } - // Files--------------------------------------------------------------------- - // @Append( - if (SameText(name, "@Append")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @Assign - if (SameText(name, "@Assign")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "S", "String"); - return true; - } - // @BlockRead - if (SameText(name, "@BlockRead")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "buffer", "Pointer"); - procInfo->AddArg(0x21, 2, 4, "recCnt", "Longint"); - procInfo->AddArg(0x22, 8, 4, "recsRead", "Longint"); - return true; - } - // @BlockWrite - if (SameText(name, "@BlockWrite")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "buffer", "Pointer"); - procInfo->AddArg(0x21, 2, 4, "recCnt", "Longint"); - procInfo->AddArg(0x22, 8, 4, "recsWritten", "Longint"); - return true; - } - // @Close - if (SameText(name, "@Close")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @EofFile - if (SameText(name, "@EofFile")) { - kind = ikFunc; - type = "Boolean"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @EofText - if (SameText(name, "@EofText")) { - kind = ikFunc; - type = "Boolean"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @Eoln - if (SameText(name, "@Eoln")) { - kind = ikFunc; - type = "Boolean"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @Erase - if (SameText(name, "@Erase")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @FilePos - if (SameText(name, "@FilePos")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @FileSize - if (SameText(name, "@FileSize")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @Flush - if (SameText(name, "@Flush")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @ReadRec - if (SameText(name, "@ReadRec")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "Buffer", "Pointer"); - return true; - } - // @ReadChar - if (SameText(name, "@ReadChar")) { - kind = ikFunc; - type = "Char"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @ReadLong - if (SameText(name, "@ReadLong")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @ReadString - if (SameText(name, "@ReadString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PShortString"); - procInfo->AddArg(0x21, 2, 4, "MaxLen", "Longint"); - return true; - } - // @ReadCString - if (SameText(name, "@ReadCString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PAnsiChar"); - procInfo->AddArg(0x21, 2, 4, "MaxLen", "Longint"); - return true; - } - // @ReadLString - if (SameText(name, "@ReadLString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x22, 1, 4, "S", "AnsiString"); - return true; - } - // @ReadWString - if (SameText(name, "@ReadWString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x22, 1, 4, "S", "WideString"); - return true; - } - // @ReadUString - if (SameText(name, "@ReadUString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x22, 1, 4, "S", "UnicodeString"); - return true; - } - // @ReadWCString - if (SameText(name, "@ReadWCString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PWideChar"); - procInfo->AddArg(0x21, 2, 4, "MaxBytes", "Longint"); - return true; - } - // @ReadWChar - if (SameText(name, "@ReadWChar")) { - kind = ikFunc; - type = "WideChar"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @ReadExt - if (SameText(name, "@ReadExt")) { - // kind = ikFunc; - // type = "Extended"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @ReadLn - if (SameText(name, "@ReadLn")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @Rename - if (SameText(name, "@Rename")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "NewName", "PChar"); - return true; - } - // @ResetFile - if (SameText(name, "@ResetFile")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "RecSize", "Longint"); - return true; - } - // @ResetText - if (SameText(name, "@ResetText")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @RewritFile - if (SameText(name, "@RewritFile")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "RecSize", "Longint"); - return true; - } - // @RewritText - if (SameText(name, "@RewritText")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - // procInfo->AddArg(0x21, 1, 4, "recSize", "Longint"); - return true; - } - // @Seek - if (SameText(name, "@Seek")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "RecNum", "Longint"); - return true; - } - // @SeekEof - if (SameText(name, "@SeekEof")) { - kind = ikFunc; - type = "Boolean"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @SeekEoln - if (SameText(name, "@SeekEoln")) { - kind = ikFunc; - type = "Boolean"; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @SetTextBuf - if (SameText(name, "@SetTextBuf")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "P", "Pointer"); - procInfo->AddArg(0x21, 2, 4, "Size", "Longint"); - return true; - } - // @Truncate - if (SameText(name, "@Truncate")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - return true; - } - // @WriteRec - if (SameText(name, "@WriteRec")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "F", "TFileRec"); - procInfo->AddArg(0x21, 1, 4, "Buffer", "Pointer"); - return true; - } - // @WriteChar - if (SameText(name, "@WriteChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "C", "AnsiChar"); - procInfo->AddArg(0x21, 2, 4, "Width", "Integer"); - return true; - } - // @Write0Char - if (SameText(name, "@Write0Char")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "C", "AnsiChar"); - return true; - } - // @WriteBool - if (SameText(name, "@WriteBool")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "Val", "Boolean"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0Bool - if (SameText(name, "@Write0Bool")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "Val", "Boolean"); - return true; - } - // @WriteLong - if (SameText(name, "@WriteLong")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "Val", "Longint"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0Long - if (SameText(name, "@Write0Long")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "Val", "Longint"); - return true; - } - // @WriteString - if (SameText(name, "@WriteString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "ShortString"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0String - if (SameText(name, "@Write0String")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "ShortString"); - return true; - } - // @WriteCString - if (SameText(name, "@WriteCString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PAnsiChar"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0CString - if (SameText(name, "@Write0CString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PAnsiChar"); - return true; - } - // @WriteLString - if (SameText(name, "@WriteLString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "AnsiString"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0LString - if (SameText(name, "@Write0LString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "AnsiString"); - return true; - } - // @Write2Ext - if (SameText(name, "@Write2Ext") || SameText(name, "@Str2Ext")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 8, 12, "Val", "Extended"); - procInfo->AddArg(0x21, 1, 4, "Width", "Longint"); - procInfo->AddArg(0x21, 2, 4, "Precision", "Longint"); - return true; - } - // @WriteWString - if (SameText(name, "@WriteWString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "WideString"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0WString - if (SameText(name, "@Write0WString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "WideString"); - return true; - } - // @WriteWCString - if (SameText(name, "@WriteWCString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PWideChar"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0WCString - if (SameText(name, "@Write0WCString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "PWideChar"); - return true; - } - // @WriteWChar - if (SameText(name, "@WriteWChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "C", "WideChar"); - procInfo->AddArg(0x21, 2, 4, "Width", "Longint"); - return true; - } - // @Write0WChar - if (SameText(name, "@Write0WChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "C", "WideChar"); - return true; - } - // @Write1Ext - if (SameText(name, "@Write1Ext")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "Width", "Longint"); - return true; - } - // @Write0Ext - if (SameText(name, "@Write0Ext")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @WriteLn - if (SameText(name, "@WriteLn")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - return true; - } - // @WriteUString - if (SameText(name, "@WriteUString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "UnicodeString"); - procInfo->AddArg(0x21, 2, 4, "Width", "Integer"); - return true; - } - // @Write0UString - if (SameText(name, "@Write0UString")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "S", "UnicodeString"); - return true; - } - // @WriteVariant - if (SameText(name, "@WriteVariant")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "V", "TVarData"); - procInfo->AddArg(0x21, 2, 4, "Width", "Integer"); - return true; - } - // @Write0Variant - if (SameText(name, "@Write0Variant")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "T", "TTextRec"); - procInfo->AddArg(0x21, 1, 4, "V", "TVarData"); - return true; - } - // Other--------------------------------------------------------------------- - // A - // function @AsClass(child:TObject; parent:TClass):TObject; - if (SameText(name, "@AsClass")) { - kind = ikFunc; - type = "TObject"; - procInfo->AddArg(0x21, 0, 4, "child", "TObject"); - procInfo->AddArg(0x21, 1, 4, "parent", "TClass"); - return true; - } - // procedure @Assert(Message: String; Filename:String; LineNumber:Integer); - if (SameText(name, "@Assert")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Message", "String"); - procInfo->AddArg(0x21, 1, 4, "Filename", "String"); - procInfo->AddArg(0x21, 2, 4, "LineNumber", "Integer"); - return true; - } - // @BoundErr - if (SameText(name, "@BoundErr")) { - kind = ikProc; - return true; - } - // @CopyArray - if (SameText(name, "@CopyArray")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Dest", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "Source", "Pointer"); - procInfo->AddArg(0x21, 2, 4, "TypeInfo", "Pointer"); - procInfo->AddArg(0x21, 8, 4, "Cnt", "Integer"); - return true; - } - // @CopyRecord - if (SameText(name, "@CopyRecord")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Dest", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "Source", "Pointer"); - procInfo->AddArg(0x21, 2, 4, "TypeInfo", "Pointer"); - return true; - } - // DynArrays - // @DynArrayAddRef - if (SameText(name, "@DynArrayAddRef")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); - return true; - } - // @DynArrayAsg - if (SameText(name, "@DynArrayAsg")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "Source", "Pointer"); - procInfo->AddArg(0x21, 2, 4, "TypeInfo", "PDynArrayTypeInfo"); - return true; - } - // @DynArrayClear - if (SameText(name, "@DynArrayClear")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Arr", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); - return true; - } - // @DynArrayCopy - if (SameText(name, "@DynArrayCopy")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); - procInfo->AddArg(0x22, 2, 4, "Result", "Pointer"); - return true; - } - // @DynArrayCopyRange - if (SameText(name, "@DynArrayCopyRange")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); - procInfo->AddArg(0x21, 2, 4, "Index", "Integer"); - procInfo->AddArg(0x21, 8, 4, "Count", "Integer"); - procInfo->AddArg(0x22, 12, 4, "Result", "Pointer"); - return true; - } - // @DynArrayHigh - if (SameText(name, "@DynArrayHigh")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); - return true; - } - // @DynArrayLength - if (SameText(name, "@DynArrayLength")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x21, 0, 4, "Arr", "Pointer"); - return true; - } - // @DynArraySetLength - if (SameText(name, "@DynArraySetLength")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Arr", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "TypeInfo", "PDynArrayTypeInfo"); - procInfo->AddArg(0x21, 2, 4, "DimCnt", "Longint"); - procInfo->AddArg(0x21, 8, 4, "LengthVec", "Longint"); - return true; - } - // @FillChar - if (SameText(name, "@FillChar")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "dst", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "cnt", "Integer"); - procInfo->AddArg(0x21, 2, 4, "val", "Char"); - return true; - } - // @FreeMem - if (SameText(name, "@FreeMem")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x21, 0, 4, "p", "Pointer"); - return true; - } - // @GetMem - if (SameText(name, "@GetMem")) { - kind = ikFunc; - type = "Pointer"; - procInfo->AddArg(0x21, 0, 4, "size", "Integer"); - return true; - } - // @IntOver - if (SameText(name, "@IntOver")) { - kind = ikProc; - return true; - } - // @IsClass - if (SameText(name, "@IsClass")) { - kind = ikFunc; - type = "Boolean"; - procInfo->AddArg(0x21, 0, 4, "Child", "TObject"); - procInfo->AddArg(0x21, 1, 4, "Parent", "TClass"); - return true; - } - // @RandInt - if (SameText(name, "@RandInt")) { - kind = ikFunc; - type = "Integer"; - procInfo->AddArg(0x21, 0, 4, "Range", "Integer"); - return true; - } - // @ReallocMem - if (SameText(name, "@ReallocMem")) { - kind = ikFunc; - type = "Pointer"; - procInfo->AddArg(0x22, 0, 4, "P", "Pointer"); - procInfo->AddArg(0x21, 1, 4, "NewSize", "Integer"); - return true; - } - // @SetElem - if (SameText(name, "@SetElem")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "Dest", "SET"); - procInfo->AddArg(0x21, 1, 1, "Elem", "Byte"); - procInfo->AddArg(0x21, 2, 1, "Size", "Byte"); - return true; - } - // Trunc - if (SameText(name, "@Trunc")) { - kind = ikFunc; - type = "Int64"; - procInfo->AddArg(0x21, 0, 12, "X", "Extended"); - return true; - } - // V - // function @ValExt(s:AnsiString; var code:Integer):Extended; - if (SameText(name, "@ValExt")) { - kind = ikProc; - procInfo->AddArg(0x21, 0, 4, "s", "AnsiString"); - procInfo->AddArg(0x22, 1, 4, "code", "Integer"); - return true; - } - // function @ValLong(s:AnsiString; var code:Integer):Longint; - if (SameText(name, "@ValLong")) { - kind = ikFunc; - type = "Longint"; - procInfo->AddArg(0x21, 0, 4, "s", "AnsiString"); - procInfo->AddArg(0x22, 1, 4, "code", "Integer"); - return true; - } - // procedure @VarFromCurr(var v: Variant; val:Currency); - if (SameText(name, "@VarFromCurr")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "v", "Variant"); - // procInfo->AddArg(0x21, ?, 8, "val", "Currency"); - return true; - } - // procedure @VarFromReal(var v:Variant; val:Real); - if (SameText(name, "@VarFromReal")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "v", "Variant"); - // procInfo->AddArg(0x21, ?, 8, "val", "Real"); fld! - return true; - } - // procedure @VarFromTDateTime(var v: Variant; val:TDateTime); - if (SameText(name, "@VarFromTDateTime")) { - kind = ikProc; - procInfo->AddArg(0x22, 0, 4, "v", "Variant"); - // procInfo->AddArg(0x21, ?, 8, "val", "TDateTime"); fld! - return true; - } - // SET - // procedure @SetRange(lo:Byte; hi:Byte; size:Byte; VAR d:SET); AL,DL,ECX,AH {Usage: d = [lo..hi]} - // function @SetEq(left:SET; right:SET; size:Byte):ZF; {Usage: left = right} - // function @SetLe(left:SET; right:SET; size:Byte):ZF; - // procedure @SetIntersect(var dest:SET; src:SET; size:Byte); - // procedure @SetIntersect3(var dest:SET; src:SET; size:Longint; src2:SET); - // procedure @SetUnion(var dest:SET; src:SET; size:Byte); - // procedure @SetUnion3(var dest:SET; src:SET; size:Longint; src2:SET); - // procedure @SetSub(var dest:SET; src:SET; size:Byte); - // procedure @SetSub3(var dest:SET; src:SET; size:Longint; src2:SET); - // procedure @SetExpand(src:SET; var dest:SET; lo:Byte; hi:Byte); EAX,EDX,CH,CL - // in <-> bt - return false; -} -// --------------------------------------------------------------------------- -/* - { Procedures and functions that need compiler magic } - procedure _COS(st0):st0; - procedure _EXP(st1):st0; - procedure _INT; - procedure _SIN(st0):st0; - procedure _FRAC; - procedure _ROUND; - - function _RandExt:Extended; ST0 - - procedure _Str2Ext(val:Extended; width:Longint; precision:Longint; var s:String); [ESP+4],EAX,EDX,ECX - procedure _Str0Ext(val:Extended; var s:String); [ESP+4],EAX - procedure _Str1Ext(val:Extended; width:Longint; var s:String); [ESP+4],EAX,EDX - function _ValExt(s:AnsiString; var code:Integer):Extended; EAX,EDX:ST0 - function _Pow10(val:Extended; Power:Integer):Extended; ST0,EAX:ST0 - procedure _Real2Ext(val:Real):Extended; EAX:ST0 - procedure _Ext2Real(val:Extended):Real; ST0,EAX - - function _ObjSetup(Self:TObject; vmtPtrOff:Longint):TObject; AD //internal - procedure _ObjCopy(Dest:TObject; Src:TObject, vmtPtrOff:Longint); ADC //internal - function _Fail(Self:TObject; allocFlag:Longint):TObject; AD //internal - - function @_llmul(val1:Int64; val2:Int64):Int64; EAX;EDX;[ESP+4] - function @_llmulo(val1:Int64; val2:Int64):Int64,OF; EAX;EDX;[ESP+4] - function @_lldiv(val1:Int64; val2:Int64):Int64; EAX;EDX;[ESP+4] - function @_lldivo(val1:Int64; val2:Int64):Int64,OF; EAX;EDX;[ESP+4] - function @_llmod(val1:Int64; val2:Int64):Int64; EAX;EDX;[ESP+4] - function @_llshl(val:Int64):Int64; EAX,EDX - function @_llushr(val:Int64):Int64; EAX,EDX - */ diff --git a/Sources/Libs/Infos.h b/Sources/Libs/Infos.h deleted file mode 100644 index 9e29cdb..0000000 --- a/Sources/Libs/Infos.h +++ /dev/null @@ -1,153 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef InfosH -#define InfosH - -#include "KnowledgeBase.h" -// --------------------------------------------------------------------------- -// lastVar -// vmtAdr -// typeIdx??? - for Type search -// --------------------------------------------------------------------------- -// Class Methods Information -typedef struct { - bool abstract; // call @AbstractError - char kind; // 'M' - method; 'V' - virtual; 'D' - dynamic - int id; // ID (for virtual methods - offset, for dynamics - MsgId) - DWORD address; // Call Address - String name; // Method Name -} MethodRec, *PMethodRec; - -// Information about class fields (look VmtSelfPtr) -#define FIELD_PRIVATE 9 -#define FIELD_PROTECTED 10 -#define FIELD_PUBLIC 11 -#define FIELD_PUBLISHED 12 - -// --------------------------------------------------------------------------- -class InfoResStringInfo { -public: - String value; -}; - -// --------------------------------------------------------------------------- -typedef InfoResStringInfo *PInfoResStringInfo; - -// --------------------------------------------------------------------------- -class InfoVmtInfo { -public: - TStringList *interfaces; - TList *fields; - TList *methods; - - __fastcall InfoVmtInfo(); - __fastcall ~InfoVmtInfo(); - void __fastcall AddInterface(String Value); - PFIELDINFO __fastcall AddField(DWORD ProcAdr, int ProcOfs, BYTE Scope, int Offset, int Case, String Name, String Type); - bool __fastcall AddMethod(bool Abstract, char Kind, int Id, DWORD Address, String Name); - void __fastcall RemoveField(int Offset); -}; - -// --------------------------------------------------------------------------- -typedef InfoVmtInfo *PInfoVmtInfo; -// --------------------------------------------------------------------------- -// procflags -#define PF_MAYBEEMBED 0x80000000 -#define PF_EMBED 0x40000000 -#define PF_VIRTUAL 0x20000000 -#define PF_DYNAMIC 0x10000000 -#define PF_EVENT 0x08000000 -#define PF_OUTEAX 0x04000000 -#define PF_KBPROTO 0x02000000 //if prototype for kb was got -#define PF_BPBASED 0x01000000 -#define PF_ARGSIZEG 0x00800000 //If delta between retN and total arguments size > 0 -#define PF_ARGSIZEL 0x00400000 //If delta between retN and total arguments size < 0 -#define PF_METHOD 0x00200000 //is method of class (other than virtual, dynamic or event) -#define PF_PUBLISHED 0x00100000 //published - -#define PF_ALLMETHODS (PF_METHOD | PF_VIRTUAL | PF_DYNAMIC | PF_EVENT) - -// first 3 bits - call kind (1, 2, 3, 4) -// --------------------------------------------------------------------------- -class InfoProcInfo { -public: - DWORD flags; - WORD bpBase; // First argument distance from base ebp - WORD retBytes; - int procSize; - int stackSize; - TList *args; - TList *locals; - - __fastcall InfoProcInfo(); - __fastcall ~InfoProcInfo(); - PARGINFO __fastcall AddArg(PARGINFO aInfo); - PARGINFO __fastcall AddArg(BYTE Tag, int Ofs, int Size, String Name, String TypeDef); - String __fastcall AddArgsFromDeclaration(char* Decl, int from, int callKind); - PARGINFO __fastcall GetArg(int n); - void __fastcall DeleteArg(int n); - void __fastcall DeleteArgs(); - PLOCALINFO __fastcall AddLocal(int Ofs, int Size, String Name, String TypeDef); - PLOCALINFO __fastcall GetLocal(int Ofs); - PLOCALINFO __fastcall GetLocal(String Name); - void __fastcall DeleteLocal(int n); - void __fastcall DeleteLocals(); - void __fastcall SetLocalType(int Ofs, String TypeDef); -}; - -// --------------------------------------------------------------------------- -typedef InfoProcInfo *PInfoProcInfo; -// --------------------------------------------------------------------------- -#define OP_COMMENT 0x10 -#define OP_CALL 0x11 -// --------------------------------------------------------------------------- -typedef struct { - BYTE Op; // Operation - union { - int Offset; // Field offset - DWORD Address; // Proc address for OP_CALL - } Ofs; - String Name; // Type name -} PICODE, *PPICODE; - -// --------------------------------------------------------------------------- -class InfoRec { -public: - BYTE counter; - BYTE kind; - int kbIdx; - String type; // Return value type for function - PPICODE picode; // Internal code - TList *xrefs; - PInfoResStringInfo rsInfo; - PInfoVmtInfo vmtInfo; - PInfoProcInfo procInfo; - -private: - String name; - -public: - __fastcall InfoRec(int APos, BYTE AKind); - __fastcall ~InfoRec(); - bool __fastcall HasName(); - String __fastcall GetName(); - int __fastcall GetNameLength(); - void __fastcall SetName(String AValue); - void __fastcall ConcatName(String AValue); - bool __fastcall SameName(String AValue); - void __fastcall AddXref(char Type, DWORD Adr, int Offset); - void __fastcall DeleteXref(DWORD Adr); - void __fastcall ScanUpItemAndAddRef(int fromPos, DWORD itemAdr, char refType, DWORD refAdr); - virtual void __fastcall Save(TStream* outs); - virtual void __fastcall Load(TStream* ins, char* buf); - // virtual void __fastcall Skip(TStream* ins, char* buf, BYTE asKind); - String __fastcall MakePrototype(int adr, bool showKind, bool showTail, bool multiline, bool fullName, bool allArgs); - String __fastcall MakeDelphiPrototype(int Adr, PMethodRec recM); - String __fastcall MakeMultilinePrototype(int Adr, int* ArgsBytes, String MethodType); - String __fastcall MakeMapName(int Adr); - bool __fastcall MakeArgsManually(); -}; - -// --------------------------------------------------------------------------- -typedef InfoRec *PInfoRec; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/KnowledgeBase.cpp b/Sources/Libs/KnowledgeBase.cpp deleted file mode 100644 index b647f95..0000000 --- a/Sources/Libs/KnowledgeBase.cpp +++ /dev/null @@ -1,2304 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -// #include //System.Assert -#include "KnowledgeBase.h" - -#include "Main.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -extern DWORD CodeBase; -extern BYTE *Code; -String __fastcall TrimTypeName(const String& TypeName); -// --------------------------------------------------------------------------- -#define cfCode 0x00000001 //Áàéò îòíîñèòñÿ ê êîäó -#define cfData 0x00000002 //Áàéò îòíîñèòñÿ ê äàííûì - -FIELDINFO::~FIELDINFO() { - CleanupList(xrefs); -} - -// --------------------------------------------------------------------------- -__fastcall MConstInfo::MConstInfo() { - ModuleID = 0xFFFF; - ConstName = ""; - Type = 0; - TypeDef = ""; - Value = ""; - DumpSz = 0; - FixupNum = 0; - Dump = 0; -} - -// --------------------------------------------------------------------------- -__fastcall MConstInfo::~MConstInfo() { - // as direct cache mem usage - // if (Dump) delete[] Dump; -} - -// --------------------------------------------------------------------------- -__fastcall MTypeInfo::MTypeInfo() { - Size = 0; - ModuleID = 0xFFFF; - TypeName = ""; - Kind = 0xFF; - VMCnt = 0; - Decl = ""; - DumpSz = 0; - FixupNum = 0; - Dump = 0; - FieldsNum = 0; - Fields = 0; - PropsNum = 0; - Props = 0; - MethodsNum = 0; - Methods = 0; -} - -// --------------------------------------------------------------------------- -__fastcall MTypeInfo::~MTypeInfo() { -} - -// --------------------------------------------------------------------------- -__fastcall MVarInfo::MVarInfo() { - ModuleID = 0xFFFF; - VarName = ""; - Type = 0; - TypeDef = ""; - AbsName = ""; -} - -// --------------------------------------------------------------------------- -__fastcall MVarInfo::~MVarInfo() { -} - -// --------------------------------------------------------------------------- -__fastcall MResStrInfo::MResStrInfo() { - ModuleID = 0xFFFF; - ResStrName = ""; - TypeDef = ""; - // AContext = ""; -} - -// --------------------------------------------------------------------------- -__fastcall MResStrInfo::~MResStrInfo() { -} - -// --------------------------------------------------------------------------- -__fastcall MProcInfo::MProcInfo() { - ModuleID = 0xFFFF; - ProcName = ""; - Embedded = false; - DumpType = 0; - MethodKind = 0; - CallKind = 0; - VProc = 0; - TypeDef = ""; - DumpSz = 0; - FixupNum = 0; - Dump = 0; - ArgsNum = 0; - Args = 0; - // LocalsNum = 0; - // Locals = 0; -} - -// --------------------------------------------------------------------------- -__fastcall MProcInfo::~MProcInfo() { -} - -// --------------------------------------------------------------------------- -__fastcall MKnowledgeBase::MKnowledgeBase() { - Inited = false; - Version = 0.0; - Handle = 0; - - Mods = 0; - ModuleOffsets = 0; - ConstOffsets = 0; - TypeOffsets = 0; - VarOffsets = 0; - ResStrOffsets = 0; - ProcOffsets = 0; - UsedProcs = 0; - - KBCache = 0; - SizeKBFile = 0; - NameKBFile = ""; -} - -// --------------------------------------------------------------------------- -__fastcall MKnowledgeBase::~MKnowledgeBase() { - Close(); -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::CheckKBFile() { - bool _isMSIL; - int _delphiVer; - DWORD _crc; - DWORD _kbVer; - char _signature[24]; - char _description[256]; - - fread(_signature, 1, 24, Handle); - fread(&_isMSIL, sizeof(_isMSIL), 1, Handle); - fread(&_delphiVer, sizeof(_delphiVer), 1, Handle); - fread(&_crc, sizeof(_crc), 1, Handle); - fread(_description, 1, 256, Handle); - fread(&_kbVer, sizeof(_kbVer), 1, Handle); - // Old format - if (!strcmp(_signature, "IDD Knowledge Base File") && _kbVer == 1) { - Version = _kbVer; - return true; - } - // New format - if (!strcmp(_signature, "IDR Knowledge Base File") && _kbVer == 2) { - Version = _kbVer; - return true; - } - return false; -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::Open(char* filename) { - if (Inited) { - if (NameKBFile == String(filename)) - return true; - Close(); - } - - Inited = false; - Handle = fopen(filename, "rb"); - if (!Handle) - return false; - - if (!CheckKBFile()) { - fclose(Handle); - Handle = 0; - return false; - } - - fseek(Handle, -4L, SEEK_END); - // Read SectionsOffset - fread(&SectionsOffset, sizeof(SectionsOffset), 1, Handle); - // Seek at SectionsOffset - fseek(Handle, SectionsOffset, SEEK_SET); - - // Read section Modules - fread(&ModuleCount, sizeof(ModuleCount), 1, Handle); - Mods = new WORD[ModuleCount + 1]; - memset(Mods, 0xFF, (ModuleCount + 1)*sizeof(WORD)); - fread(&MaxModuleDataSize, sizeof(MaxModuleDataSize), 1, Handle); - ModuleOffsets = new OFFSETSINFO[ModuleCount]; - fread(ModuleOffsets, sizeof(OFFSETSINFO), ModuleCount, Handle); - // Read section Consts - fread(&ConstCount, sizeof(ConstCount), 1, Handle); - fread(&MaxConstDataSize, sizeof(MaxConstDataSize), 1, Handle); - ConstOffsets = new OFFSETSINFO[ConstCount]; - fread((BYTE*)ConstOffsets, sizeof(OFFSETSINFO), ConstCount, Handle); - // Read section Types - fread(&TypeCount, sizeof(TypeCount), 1, Handle); - fread(&MaxTypeDataSize, sizeof(MaxTypeDataSize), 1, Handle); - TypeOffsets = new OFFSETSINFO[TypeCount]; - fread((BYTE*)TypeOffsets, sizeof(OFFSETSINFO), TypeCount, Handle); - // Read section Vars - fread(&VarCount, sizeof(VarCount), 1, Handle); - fread(&MaxVarDataSize, sizeof(MaxVarDataSize), 1, Handle); - VarOffsets = new OFFSETSINFO[VarCount]; - fread((BYTE*)VarOffsets, sizeof(OFFSETSINFO), VarCount, Handle); - // Read section ResStr - fread(&ResStrCount, sizeof(ResStrCount), 1, Handle); - fread(&MaxResStrDataSize, sizeof(MaxResStrDataSize), 1, Handle); - ResStrOffsets = new OFFSETSINFO[ResStrCount]; - fread((BYTE*)ResStrOffsets, sizeof(OFFSETSINFO), ResStrCount, Handle); - // Read section Procs - fread(&ProcCount, sizeof(ProcCount), 1, Handle); - fread(&MaxProcDataSize, sizeof(MaxProcDataSize), 1, Handle); - ProcOffsets = new OFFSETSINFO[ProcCount]; - fread((BYTE*)ProcOffsets, sizeof(OFFSETSINFO), ProcCount, Handle); - UsedProcs = new BYTE[ProcCount]; - memset(UsedProcs, 0, ProcCount); - - // as global KB file cache in RAM (speed up 3..4 times!) - fseek(Handle, 0L, SEEK_END); - SizeKBFile = ftell(Handle); - if (SizeKBFile > 0) { - KBCache = new BYTE[SizeKBFile]; - if (KBCache) { - fseek(Handle, 0L, SEEK_SET); - fread((BYTE*)KBCache, 1, SizeKBFile, Handle); - } - } - fclose(Handle); - Handle = 0; - - NameKBFile = String(filename); - Inited = true; - return true; -} - -// --------------------------------------------------------------------------- -void __fastcall MKnowledgeBase::Close() { - if (Inited) { - if (Mods) - delete[]Mods; - if (ModuleOffsets) - delete[]ModuleOffsets; - if (ConstOffsets) - delete[]ConstOffsets; - if (TypeOffsets) - delete[]TypeOffsets; - if (VarOffsets) - delete[]VarOffsets; - if (ResStrOffsets) - delete[]ResStrOffsets; - if (ProcOffsets) - delete[]ProcOffsets; - if (UsedProcs) - delete[]UsedProcs; - - // as - if (KBCache) - delete[]KBCache; - Inited = false; - } -} - -// --------------------------------------------------------------------------- -WORD __fastcall MKnowledgeBase::GetModuleID(char* ModuleName) { - if (!Inited) - return 0xFFFF; - - if (!ModuleName || !*ModuleName || !ModuleCount) - return 0xFFFF; - - int ID, F = 0, L = ModuleCount - 1; - const BYTE* p; - while (F < L) { - int M = (F + L) / 2; - ID = ModuleOffsets[M].NamId; - p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); - if (stricmp(ModuleName, p + 4) <= 0) - L = M; - else - F = M + 1; - } - ID = ModuleOffsets[L].NamId; - p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); - if (!stricmp(ModuleName, p + 4)) - return*((WORD*)p); - return 0xFFFF; -} - -// --------------------------------------------------------------------------- -String __fastcall MKnowledgeBase::GetModuleName(WORD ModuleID) { - if (!Inited) - return ""; - - if (ModuleID == 0xFFFF || !ModuleCount) - return ""; - - int ID, F = 0, L = ModuleCount - 1; - const BYTE* p; - WORD ModID; - while (F < L) { - int M = (F + L) / 2; - ID = ModuleOffsets[M].ModId; - p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModuleID <= ModID) - L = M; - else - F = M + 1; - } - ID = ModuleOffsets[L].ModId; - p = GetKBCachePtr(ModuleOffsets[ID].Offset, ModuleOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModuleID == ModID) - return String((char*)(p + 4)); - return ""; -} - -// --------------------------------------------------------------------------- -// Return modules ids list containing given proc -void __fastcall MKnowledgeBase::GetModuleIdsByProcName(char* AProcName) { - Mods[0] = 0xFFFF; - - if (!Inited) - return; - - if (!AProcName || !*AProcName || !ProcCount) - return; - - int L = 0, R = ProcCount - 1, n; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - int res = stricmp(AProcName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(AProcName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(AProcName, p + 4); - if (res) - break; - } - - n = 0; - for (int N = LN + 1; N < RN; N++) { - ID = ProcOffsets[N].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - Mods[n] = *((WORD*)p); - n++; - } - Mods[n] = 0xFFFF; - return; - } - if (L > R) - return; - } -} - -// --------------------------------------------------------------------------- -// Return sections containing given ItemName -int __fastcall MKnowledgeBase::GetItemSection(WORD* ModuleIDs, char* ItemName) { - bool found; - int L, R, M, ID, N, LN, RN, Result = KB_NO_SECTION; - - if (!Inited) - return Result; - - if (!ItemName || *ItemName == 0) - return Result; - WORD ModuleID, ModID; - // CONST - if (ConstCount) { - L = 0; - R = ConstCount - 1; - while (1) { - M = (L + R) / 2; - ID = ConstOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - int res = stricmp(ItemName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ConstOffsets[LN].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ConstCount; RN++) { - ID = ConstOffsets[RN].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - found = false; - for (N = LN + 1; N < RN; N++) { - ID = ConstOffsets[N].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - ModID = *((WORD*)p); - for (int n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) { - Result |= KB_CONST_SECTION; - found = true; - break; - } - } - if (found) - break; - } - break; - } - if (L > R) - break; - } - } - // TYPE - if (TypeCount) { - L = 0; - R = TypeCount - 1; - while (1) { - M = (L + R) / 2; - ID = TypeOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - int res = stricmp(ItemName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = TypeOffsets[LN].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - res = stricmp(ItemName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < TypeCount; RN++) { - ID = TypeOffsets[RN].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - res = stricmp(ItemName, p + 4); - if (res) - break; - } - found = false; - for (N = LN + 1; N < RN; N++) { - ID = TypeOffsets[N].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - ModID = *((WORD*)p); - for (int n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) { - Result |= KB_TYPE_SECTION; - found = true; - break; - } - } - if (found) - break; - } - break; - } - if (L > R) - break; - } - } - // VAR - if (VarCount) { - L = 0; - R = VarCount - 1; - while (1) { - M = (L + R) / 2; - ID = VarOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - int res = stricmp(ItemName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = VarOffsets[LN].NamId; - p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < VarCount; RN++) { - ID = VarOffsets[RN].NamId; - p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - found = false; - for (N = LN + 1; N < RN; N++) { - ID = VarOffsets[N].NamId; - p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - ModID = *((WORD*)p); - for (int n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) { - Result |= KB_VAR_SECTION; - found = true; - break; - } - } - if (found) - break; - } - break; - } - if (L > R) - break; - } - } - // RESSTR - if (ResStrCount) { - L = 0; - R = ResStrCount - 1; - while (1) { - M = (L + R) / 2; - ID = ResStrOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - int res = stricmp(ItemName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ResStrOffsets[LN].NamId; - p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ResStrCount; RN++) { - ID = ResStrOffsets[RN].NamId; - p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - found = false; - for (N = LN + 1; N < RN; N++) { - ID = ResStrOffsets[N].NamId; - p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - ModID = *((WORD*)p); - for (int n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) { - Result |= KB_RESSTR_SECTION; - found = true; - break; - } - } - if (found) - break; - } - break; - } - if (L > R) - break; - } - } - // PROC - if (ProcCount) { - L = 0; - R = ProcCount - 1; - while (1) { - M = (L + R) / 2; - ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - int res = stricmp(ItemName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ItemName, p + 4); - if (res) - break; - } - found = false; - for (N = LN + 1; N < RN; N++) { - ID = ProcOffsets[N].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - for (int n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) { - Result |= KB_PROC_SECTION; - found = true; - break; - } - } - if (found) - break; - } - break; - } - if (L > R) - break; - } - } - return Result; -} - -// --------------------------------------------------------------------------- -// Return constant index by name in given ModuleID -int __fastcall MKnowledgeBase::GetConstIdx(WORD* ModuleIDs, char* ConstName) { - if (!Inited) - return -1; - - if (!ModuleIDs || !ConstName || !*ConstName || !ConstCount) - return -1; - - WORD ModuleID, ModID; - int n, L = 0, R = ConstCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ConstOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - int res = stricmp(ConstName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ConstOffsets[LN].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - res = stricmp(ConstName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ConstCount; RN++) { - ID = ConstOffsets[RN].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - res = stricmp(ConstName, p + 4); - if (res) - break; - } - for (int N = LN + 1; N < RN; N++) { - ID = ConstOffsets[N].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - ModID = *((WORD*)p); - - for (n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) - return N; - } - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetConstIdxs(char* ConstName, int* ConstIdx) { - *ConstIdx = -1; - - if (!Inited) - return 0; - - if (!ConstName || !*ConstName || !ConstCount) - return 0; - - int L = 0, R = ConstCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ConstOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - int res = stricmp(ConstName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int Num = 1; - *ConstIdx = M; - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ConstOffsets[LN].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - if (stricmp(ConstName, p + 4)) - break; - Num++; - } - // Find right boundary - for (RN = M + 1; RN < ConstCount; RN++) { - ID = ConstOffsets[RN].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - if (stricmp(ConstName, p + 4)) - break; - Num++; - } - return Num; - } - if (L > R) - return 0; - } -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetTypeIdxByModuleIds(WORD* ModuleIDs, char* TypeName) { - if (!Inited) - return -1; - - if (!ModuleIDs || !TypeName || !*TypeName || !TypeCount) - return -1; - - WORD ModuleID, ModID; - int n, L = 0, R = TypeCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = TypeOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - int res = stricmp(TypeName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = TypeOffsets[LN].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - res = stricmp(TypeName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < TypeCount; RN++) { - ID = TypeOffsets[RN].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - res = stricmp(TypeName, p + 4); - if (res) - break; - } - for (int N = LN + 1; N < RN; N++) { - ID = TypeOffsets[N].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - ModID = *((WORD*)p); - - for (n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) - return N; - } - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetTypeIdxsByName(char* TypeName, int* TypeIdx) { - *TypeIdx = -1; - - if (!Inited) - return 0; - - if (!TypeName || !*TypeName || !TypeCount) - return 0; - - int L = 0, R = TypeCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = TypeOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - int res = stricmp(TypeName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int Num = 1; - *TypeIdx = M; - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = TypeOffsets[LN].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - if (stricmp(TypeName, p + 4)) - break; - Num++; - } - // Find right boundary - for (RN = M + 1; RN < TypeCount; RN++) { - ID = TypeOffsets[RN].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - if (stricmp(TypeName, p + 4)) - break; - Num++; - } - return Num; - } - if (L > R) - return 0; - } -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetTypeIdxByUID(char* UID) { -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetVarIdx(WORD* ModuleIDs, char* VarName) { - if (!Inited) - return -1; - - if (!ModuleIDs || !VarName || !*VarName || !VarCount) - return -1; - - WORD ModuleID, ModID, len; - int n, L = 0, R = VarCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = VarOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - int res = stricmp(VarName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = VarOffsets[LN].NamId; - p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - res = stricmp(VarName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < VarCount; RN++) { - ID = VarOffsets[RN].NamId; - p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - res = stricmp(VarName, p + 4); - if (res) - break; - } - for (int N = LN + 1; N < RN; N++) { - ID = VarOffsets[N].NamId; - p = GetKBCachePtr(VarOffsets[ID].Offset, VarOffsets[ID].Size); - ModID = *((WORD*)p); - for (n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) - return N; - } - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetResStrIdx(int from, char* ResStrContext) { - if (!Inited) - return -1; - - if (!ResStrContext || !*ResStrContext || !ResStrCount) - return -1; - - int n, ID; - for (n = from; n < ResStrCount; n++) { - ID = ResStrOffsets[n].NamId; - const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - // ModuleID - p += 2; - // ResStrName - WORD len = *((WORD*)p); - p += len + 3; - // TypeDef - len = *((WORD*)p); - p += len + 5; - // Context - if (!stricmp(ResStrContext, p)) { - return n; - } - } - return -1; -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetResStrIdx(WORD ModuleID, char* ResStrContext) { - if (!Inited) - return -1; - - if (!ResStrContext || !*ResStrContext || !ResStrCount) - return -1; - - WORD ModID, len; - int n, ID; - - for (n = 0; n < ResStrCount; n++) { - ID = ResStrOffsets[n].NamId; - const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - // ModuleID - ModID = *((WORD*)p); - p += 2; - // ResStrName - len = *((WORD*)p); - p += len + 3; - // TypeDef - len = *((WORD*)p); - p += len + 5; - // Context - if (ModuleID == ModID && !stricmp(ResStrContext, p)) { - return n; - } - } - return -1; -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetResStrIdx(WORD* ModuleIDs, char* ResStrName) { - if (!Inited) - return -1; - - if (!ModuleIDs || !ResStrName || !*ResStrName || !ResStrCount) - return -1; - - WORD ModuleID, ModID, len; - int n, L = 0, R = ResStrCount - 1, M, ID, res, LN, RN, N; - - while (1) { - M = (L + R) / 2; - ID = ResStrOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - res = stricmp(ResStrName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ResStrOffsets[LN].NamId; - p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - res = stricmp(ResStrName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ResStrCount; RN++) { - ID = ResStrOffsets[RN].NamId; - p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - res = stricmp(ResStrName, p + 4); - if (res) - break; - } - for (N = LN + 1; N < RN; N++) { - ID = ResStrOffsets[N].NamId; - p = GetKBCachePtr(ResStrOffsets[ID].Offset, ResStrOffsets[ID].Size); - ModID = *((WORD*)p); - for (n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) - return N; - } - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -// Return proc index by name in given ModuleID -int __fastcall MKnowledgeBase::GetProcIdx(WORD ModuleID, char* ProcName) { - if (!Inited) - return -1; - - if (ModuleID == 0xFFFF || !ProcName || !*ProcName || !ProcCount) - return -1; - - WORD ModID; - int L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - int res = stricmp(ProcName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - for (int N = LN + 1; N < RN; N++) { - ID = ProcOffsets[N].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModuleID == ModID) - return N; - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -// Return proc index by name in given ModuleID -// Code used for selection required proc (if there are exist several procs with the same name) -int __fastcall MKnowledgeBase::GetProcIdx(WORD ModuleID, char* ProcName, BYTE* code) { - if (!Inited) - return -1; - - if (ModuleID == 0xFFFF || !ProcName || !*ProcName || !ProcCount) - return -1; - - MProcInfo aInfo; - MProcInfo* pInfo; - WORD ModID; - int L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - int res = stricmp(ProcName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - for (int N = LN + 1; N < RN; N++) { - pInfo = GetProcInfo(ProcOffsets[N].NamId, INFO_DUMP, &aInfo); - ModID = pInfo->ModuleID; - bool match = MatchCode(code, pInfo); - if (match && ModuleID == ModID) - return N; - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -// Return proc index by name in given array of ModuleID -int __fastcall MKnowledgeBase::GetProcIdx(WORD* ModuleIDs, char* ProcName, BYTE* code) { - if (!Inited) - return -1; - - if (!ModuleIDs || !ProcName || !*ProcName || !ProcCount) - return -1; - - MProcInfo aInfo; - MProcInfo* pInfo; - WORD ModuleID, ModID; - int n, L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - int res = stricmp(ProcName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - for (int N = LN + 1; N < RN; N++) { - pInfo = GetProcInfo(ProcOffsets[N].NamId, INFO_DUMP, &aInfo); - ModID = pInfo->ModuleID; - if (code) { - bool match = MatchCode(code, pInfo); - if (match) { - for (n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) - return N; - } - } - } - else { - for (n = 0; ; n++) { - ModuleID = ModuleIDs[n]; - if (ModuleID == 0xFFFF) - break; - if (ModuleID == ModID) - return N; - } - } - } - // Nothing found - exit - return -1; - } - if (L > R) - return -1; - } -} - -// --------------------------------------------------------------------------- -// Seek first ans last proc ID in given module -bool __fastcall MKnowledgeBase::GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx) { - if (!Inited) - return false; - - if (ModuleID == 0xFFFF || !ProcCount || !FirstProcIdx || !LastProcIdx) - return false; - - *FirstProcIdx = -1; - *LastProcIdx = -1; - WORD ModID; - int L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].ModId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - - if (ModuleID < ModID) - R = M - 1; - else if (ModuleID > ModID) - L = M + 1; - else { - *FirstProcIdx = M; - *LastProcIdx = M; - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].ModId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModID != ModuleID) - break; - *FirstProcIdx = LN; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].ModId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModID != ModuleID) - break; - *LastProcIdx = RN; - } - return true; - } - if (L > R) - return false; - } -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx, int* DumpSize) { - if (!Inited || ModuleID == 0xFFFF || !ProcCount) - return false; - - *FirstProcIdx = -1; - *LastProcIdx = -1; - *DumpSize = 0; - WORD ModID; - int L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].ModId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - - if (ModuleID < ModID) - R = M - 1; - else if (ModuleID > ModID) - L = M + 1; - else { - *FirstProcIdx = M; - *LastProcIdx = M; - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].ModId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModID != ModuleID) - break; - *FirstProcIdx = LN; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].ModId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - ModID = *((WORD*)p); - if (ModID != ModuleID) - break; - *LastProcIdx = RN; - } - for (int m = *FirstProcIdx; m <= *LastProcIdx; m++) { - p = GetKBCachePtr(ProcOffsets[m].Offset, ProcOffsets[m].Size); - // ModuleID - p += 2; - // ProcName - WORD Len = *((WORD*)p); - p += Len + 3; - // Embedded - p++; - // DumpType - p++; - // MethodKind - p++; - // CallKind - p++; - // VProc - p += 4; - // TypeDef - Len = *((WORD*)p); - p += Len + 3; - // DumpTotal - p += 4; - // DumpSz - int size = *((DWORD*)p); - *DumpSize += (size + 3) & (-4); - } - return true; - } - if (L > R) - return false; - } -} - -// --------------------------------------------------------------------------- -// ConstIdx was given by const name -MConstInfo* __fastcall MKnowledgeBase::GetConstInfo(int AConstIdx, DWORD AFlags, MConstInfo* cInfo) { - if (!Inited) - return 0; - - if (AConstIdx == -1) - return 0; - - const BYTE* p = GetKBCachePtr(ConstOffsets[AConstIdx].Offset, ConstOffsets[AConstIdx].Size); - cInfo->ModuleID = *((WORD*)p); - p += 2; - WORD Len = *((WORD*)p); - p += 2; - cInfo->ConstName = String((char*)p); - p += Len + 1; - cInfo->Type = *p; - p++; - Len = *((WORD*)p); - p += 2; - cInfo->TypeDef = String((char*)p); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - cInfo->Value = String((char*)p); - p += Len + 1; - - DWORD DumpTotal = *((DWORD*)p); - p += 4; - cInfo->DumpSz = *((DWORD*)p); - p += 4; - cInfo->FixupNum = *((DWORD*)p); - p += 4; - cInfo->Dump = 0; - - if (AFlags & INFO_DUMP) { - if (cInfo->DumpSz) - cInfo->Dump = (BYTE*)p; - } - return cInfo; -} - -// --------------------------------------------------------------------------- -MProcInfo* __fastcall MKnowledgeBase::GetProcInfo(char* ProcName, DWORD AFlags, MProcInfo *pInfo, int *procIdx) { - if (!Inited) - return 0; - - if (!ProcName || !*ProcName || !ProcCount) - return 0; - - WORD ModID; - int L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - int res = stricmp(ProcName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - int LN, RN; - // Find left boundary - for (LN = M - 1; LN >= 0; LN--) { - ID = ProcOffsets[LN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - // Find right boundary - for (RN = M + 1; RN < ProcCount; RN++) { - ID = ProcOffsets[RN].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - } - if (RN - LN - 1 == 1) { - ID = ProcOffsets[M].NamId; - *procIdx = ID; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - - pInfo->ModuleID = *((WORD*)p); - p += 2; - WORD Len = *((WORD*)p); - p += 2; - pInfo->ProcName = String((char*)p); - p += Len + 1; - pInfo->Embedded = *p; - p++; - pInfo->DumpType = *p; - p++; - pInfo->MethodKind = *p; - p++; - pInfo->CallKind = *p; - p++; - pInfo->VProc = *((int*)p); - p += 4; - Len = *((WORD*)p); - p += 2; - pInfo->TypeDef = TrimTypeName(String((char*)p)); - p += Len + 1; - - DWORD DumpTotal = *((DWORD*)p); - p += 4; - const BYTE *p1 = p; - pInfo->DumpSz = *((DWORD*)p); - p += 4; - pInfo->FixupNum = *((DWORD*)p); - p += 4; - pInfo->Dump = 0; - - if (AFlags & INFO_DUMP) { - if (pInfo->DumpSz) - pInfo->Dump = (BYTE*)p; - } - p = p1 + DumpTotal; - - DWORD ArgsTotal = *((DWORD*)p); - p += 4; - p1 = p; - pInfo->ArgsNum = *((WORD*)p); - p += 2; - pInfo->Args = 0; - - if (AFlags & INFO_ARGS) { - if (pInfo->ArgsNum) - pInfo->Args = (BYTE*)p; - } - p = p1 + ArgsTotal; - /* - DWORD LocalsTotal = *((DWORD*)p); p += 4; - pInfo->LocalsNum = *((WORD*)p); p += 2; - pInfo->Locals = 0; - - if (AFlags & INFO_LOCALS) - { - if (pInfo->LocalsNum) pInfo->Locals = (BYTE*)p; - } - */ - return pInfo; - } - // More than 2 items found - /* - for (int nnn = LN + 1; nnn <= RN - 1; nnn++) - { - ID = ProcOffsets[nnn].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - - pInfo->ModuleID = *((WORD*)p); p += 2; - WORD Len = *((WORD*)p); p += 2; - pInfo->ProcName = String((char*)p); p += Len + 1; - pInfo->Embedded = *p; p++; - pInfo->DumpType = *p; p++; - pInfo->MethodKind = *p; p++; - pInfo->CallKind = *p; p++; - pInfo->VProc = *((int*)p); p += 4; - Len = *((WORD*)p); p += 2; - pInfo->TypeDef = TrimTypeName(String((char*)p)); p += Len + 1; - - DWORD DumpTotal = *((DWORD*)p); p += 4; - const BYTE *p1 = p; - pInfo->DumpSz = *((DWORD*)p); p += 4; - pInfo->FixupNum = *((DWORD*)p); p += 4; - pInfo->Dump = 0; - - if (AFlags & INFO_DUMP) - { - if (pInfo->DumpSz) pInfo->Dump = (BYTE*)p; - } - p = p1 + DumpTotal; - - DWORD ArgsTotal = *((DWORD*)p); p += 4; - p1 = p; - pInfo->ArgsNum = *((WORD*)p); p += 2; - pInfo->Args = 0; - - if (AFlags & INFO_ARGS) - { - if (pInfo->ArgsNum) pInfo->Args = (BYTE*)p; - } - } - */ - return (MProcInfo*)-1; - } - if (L > R) - return 0; - } -} - -// --------------------------------------------------------------------------- -MProcInfo* __fastcall MKnowledgeBase::GetProcInfo(int AProcIdx, DWORD AFlags, MProcInfo *pInfo) { - if (!Inited) - return 0; - - if (AProcIdx == -1) - return 0; - - const BYTE *p = GetKBCachePtr(ProcOffsets[AProcIdx].Offset, ProcOffsets[AProcIdx].Size); - - pInfo->ModuleID = *((WORD*)p); - p += 2; - WORD Len = *((WORD*)p); - p += 2; - pInfo->ProcName = String((char*)p); - p += Len + 1; - pInfo->Embedded = *p; - p++; - pInfo->DumpType = *p; - p++; - pInfo->MethodKind = *p; - p++; - pInfo->CallKind = *p; - p++; - pInfo->VProc = *((int*)p); - p += 4; - Len = *((WORD*)p); - p += 2; - pInfo->TypeDef = TrimTypeName(String((char*)p)); - p += Len + 1; - - DWORD DumpTotal = *((DWORD*)p); - p += 4; - const BYTE *p1 = p; - pInfo->DumpSz = *((DWORD*)p); - p += 4; - pInfo->FixupNum = *((DWORD*)p); - p += 4; - pInfo->Dump = 0; - - if (AFlags & INFO_DUMP) { - if (pInfo->DumpSz) - pInfo->Dump = (BYTE*)p; - } - p = p1 + DumpTotal; - - DWORD ArgsTotal = *((DWORD*)p); - p += 4; - p1 = p; - pInfo->ArgsNum = *((WORD*)p); - p += 2; - pInfo->Args = 0; - - if (AFlags & INFO_ARGS) { - if (pInfo->ArgsNum) - pInfo->Args = (BYTE*)p; - } - p = p1 + ArgsTotal; - /* - DWORD LocalsTotal = *((DWORD*)p); p += 4; - pInfo->LocalsNum = *((WORD*)p); p += 2; - pInfo->Locals = 0; - - if (AFlags & INFO_LOCALS) - { - if (pInfo->LocalsNum) pInfo->Locals = (BYTE*)p; - } - */ - return pInfo; -} - -// --------------------------------------------------------------------------- -MTypeInfo* __fastcall MKnowledgeBase::GetTypeInfo(int ATypeIdx, DWORD AFlags, MTypeInfo *tInfo) { - if (!Inited) - return 0; - - if (ATypeIdx == -1) - return 0; - - const BYTE* p = GetKBCachePtr(TypeOffsets[ATypeIdx].Offset, TypeOffsets[ATypeIdx].Size); - - // Modified by ZGL - if (Version == 1) - tInfo->Size = TypeOffsets[ATypeIdx].Size; - else - tInfo->Size = *((DWORD*)p); - p += 4; - - tInfo->ModuleID = *((WORD*)p); - p += 2; - WORD Len = *((WORD*)p); - p += 2; - tInfo->TypeName = String((char*)p); - p += Len + 1; - tInfo->Kind = *p; - p++; - tInfo->VMCnt = *((WORD*)p); - p += 2; - Len = *((WORD*)p); - p += 2; - tInfo->Decl = String((char*)p); - p += Len + 1; - - DWORD DumpTotal = *((DWORD*)p); - p += 4; - BYTE *p1 = (BYTE*)p; - tInfo->DumpSz = *((DWORD*)p); - p += 4; - tInfo->FixupNum = *((DWORD*)p); - p += 4; - tInfo->Dump = 0; - - if (AFlags & INFO_DUMP) { - if (tInfo->DumpSz) - tInfo->Dump = (BYTE*)p; - } - p = p1 + DumpTotal; - - DWORD FieldsTotal = *((DWORD*)p); - p += 4; - p1 = (BYTE*)p; - tInfo->FieldsNum = *((WORD*)p); - p += 2; - tInfo->Fields = 0; - - if (AFlags & INFO_FIELDS) { - if (tInfo->FieldsNum) - tInfo->Fields = (BYTE*)p; - } - p = p1 + FieldsTotal; - - DWORD PropsTotal = *((DWORD*)p); - p += 4; - p1 = (BYTE*)p; - tInfo->PropsNum = *((WORD*)p); - p += 2; - tInfo->Props = 0; - - if (AFlags & INFO_PROPS) { - if (tInfo->PropsNum) - tInfo->Props = (BYTE*)p; - } - p = p1 + PropsTotal; - - DWORD MethodsTotal = *((DWORD*)p); - p += 4; - tInfo->MethodsNum = *((WORD*)p); - p += 2; - tInfo->Methods = 0; - - if (AFlags & INFO_METHODS) { - if (tInfo->MethodsNum) - tInfo->Methods = (BYTE*)p; - } - return tInfo; -} - -// --------------------------------------------------------------------------- -MVarInfo* __fastcall MKnowledgeBase::GetVarInfo(int AVarIdx, DWORD AFlags, MVarInfo* vInfo) { - if (!Inited) - return 0; - - if (AVarIdx == -1) - return 0; - - const BYTE* p = GetKBCachePtr(VarOffsets[AVarIdx].Offset, VarOffsets[AVarIdx].Size); - - vInfo->ModuleID = *((WORD*)p); - p += 2; - WORD Len = *((WORD*)p); - p += 2; - vInfo->VarName = String((char*)p); - p += Len + 1; - vInfo->Type = *p; - p++; - Len = *((WORD*)p); - p += 2; - vInfo->TypeDef = String((char*)p); - p += Len + 1; - - if (AFlags & INFO_ABSNAME) { - Len = *((WORD*)p); - p += 2; - vInfo->AbsName = String((char*)p); - } - - return vInfo; -} - -// --------------------------------------------------------------------------- -MResStrInfo* __fastcall MKnowledgeBase::GetResStrInfo(int AResStrIdx, DWORD AFlags, MResStrInfo* rsInfo) { - if (!Inited) - return 0; - - if (AResStrIdx == -1) - return 0; - - const BYTE* p = GetKBCachePtr(ResStrOffsets[AResStrIdx].Offset, ResStrOffsets[AResStrIdx].Size); - - rsInfo->ModuleID = *((WORD*)p); - p += 2; - WORD Len = *((WORD*)p); - p += 2; - rsInfo->ResStrName = String((char*)p); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - rsInfo->TypeDef = String((char*)p); - p += Len + 1; - - if (AFlags & INFO_DUMP) { - // Len = *((WORD*)p); p += 2; - // rsInfo->AContext = String((char*)p); - } - - return rsInfo; -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::ScanCode(BYTE* code, DWORD* CodeFlags, DWORD CodeSz, MProcInfo* pInfo) { - if (!Inited) - return -1; - - if (!pInfo) - return -1; - - DWORD DumpSz = pInfo->DumpSz; - if (!DumpSz || DumpSz >= CodeSz) - return -1; - BYTE* Dump = pInfo->Dump; - BYTE* Relocs = Dump + DumpSz; - int i, n; - - // Skip relocs in dump begin - for (n = 0; n < DumpSz; n++) { - if (Relocs[n] != 0xFF) - break; - } - for (int i = n; i < CodeSz - DumpSz + n; i++) { - if (code[i] == Dump[n] && (CodeFlags[i] & cfCode) == 0 && (CodeFlags[i] & cfData) == 0) { - bool found = true; - for (int k = n; k < DumpSz; k++) { - if ((CodeFlags[i - n + k] & cfCode) != 0 || (CodeFlags[i - n + k] & cfData) != 0) { - found = false; - break; - } - if (code[i - n + k] != Dump[k] && Relocs[k] != 0xFF) { - found = false; - break; - } - } - if (found) { - // If "tail" matched (from position i - n), check "head" - found = true; - for (int k = 0; k < n; k++) { - if ((CodeFlags[i - n + k] & cfCode) != 0 || (CodeFlags[i - n + k] & cfData) != 0) { - found = false; - break; - } - } - if (found) - return i - n; - } - } - } - return -1; -} - -// --------------------------------------------------------------------------- -// Fill used modules ids array + module itself -WORD* __fastcall MKnowledgeBase::GetModuleUses(WORD ModuleID) { - if (!Inited) - return 0; - - if (ModuleID == 0xFFFF) - return 0; - - const BYTE* p = GetKBCachePtr(ModuleOffsets[ModuleID].Offset, ModuleOffsets[ModuleID].Size); - - // ID - p += 2; - // Name - WORD len = *((WORD*)p); - p += len + 3; - // Filename - len = *((WORD*)p); - p += len + 3; - // UsesNum - WORD UsesNum = *((WORD*)p); - WORD *uses = new WORD[UsesNum + 2]; - uses[0] = ModuleID; - int m = 1; - if (UsesNum) { - p += 2; - for (int n = 0; n < UsesNum; n++) { - WORD ID = *((WORD*)p); - p += 2; - if (ID != 0xFFFF) { - uses[m] = ID; - m++; - } - } - } - uses[m] = 0xFFFF; - return uses; -} - -// --------------------------------------------------------------------------- -int __fastcall MKnowledgeBase::GetProcUses(char* ProcName, WORD* uses) { - if (!Inited) - return 0; - - int num = 0; - - int L = 0, R = ProcCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = ProcOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - - int res = stricmp(ProcName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - WORD ModID = *((WORD*)p); - if (ModID != 0xFFFF) { - uses[num] = ModID; - num++; - } - // Take ModuleIDs in same name block (firstly from right to left) - for (int N = M - 1; N >= 0; N--) { - ID = ProcOffsets[N].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - ModID = *((WORD*)p); - if (ModID != 0xFFFF && uses[num - 1] != ModID) { - uses[num] = ModID; - num++; - assert(num < ModuleCount); - } - } - // From ltft to right - for (int N = M + 1; N < ProcCount; N++) { - ID = ProcOffsets[N].NamId; - p = GetKBCachePtr(ProcOffsets[ID].Offset, ProcOffsets[ID].Size); - res = stricmp(ProcName, p + 4); - if (res) - break; - ModID = *((WORD*)p); - if (ModID != 0xFFFF && uses[num - 1] != ModID) { - uses[num] = ModID; - num++; - assert(num < ModuleCount); - } - } - return num; - } - if (L > R) - return 0; - } -} - -// --------------------------------------------------------------------------- -WORD* __fastcall MKnowledgeBase::GetTypeUses(char* TypeName) { - if (!Inited) - return 0; - - int num = 0; - WORD *uses = 0; - - int L = 0, R = TypeCount - 1; - while (1) { - int M = (L + R) / 2; - int ID = TypeOffsets[M].NamId; - const BYTE* p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - - int res = stricmp(TypeName, p + 4); - if (res < 0) - R = M - 1; - else if (res > 0) - L = M + 1; - else { - uses = new WORD[ModuleCount + 1]; - WORD ModID = *((WORD*)p); - if (ModID != 0xFFFF) { - uses[num] = ModID; - num++; - } - // Take ModuleIDs in same name block (firstly from right to left) - for (int N = M - 1; N >= 0; N--) { - ID = TypeOffsets[N].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - res = stricmp(TypeName, p + 4); - if (res) - break; - ModID = *((WORD*)p); - if (ModID != 0xFFFF && uses[num - 1] != ModID) { - uses[num] = ModID; - num++; - assert(num < ModuleCount); - } - } - // From left to right - for (int N = M + 1; N < TypeCount; N++) { - ID = TypeOffsets[N].NamId; - p = GetKBCachePtr(TypeOffsets[ID].Offset, TypeOffsets[ID].Size); // + 4; - if (Version >= 2) - p += 4; // Add by ZGL - res = stricmp(TypeName, p + 4); - if (res) - break; - ModID = *((WORD*)p); - if (ModID != 0xFFFF && uses[num - 1] != ModID) { - uses[num] = ModID; - num++; - assert(num < ModuleCount); - } - } - // After last element must be word 0xFFFF - uses[num] = 0xFFFF; - return uses; - } - if (L > R) - return 0; - } -} - -// --------------------------------------------------------------------------- -WORD* __fastcall MKnowledgeBase::GetConstUses(char* ConstName) { - if (!Inited) - return 0; - - int ID, num; - WORD ModID, *uses = 0; - const BYTE *p; - - int F = 0, L = ConstCount - 1; - while (F < L) { - int M = (F + L) / 2; - ID = ConstOffsets[M].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - if (stricmp(ConstName, p + 4) <= 0) - L = M; - else - F = M + 1; - } - ID = ConstOffsets[L].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - if (!stricmp(ConstName, p + 4)) { - uses = new WORD[ModuleCount + 1]; - num = 0; - ModID = *((WORD*)p); - if (ModID != 0xFFFF) { - uses[num] = ModID; - num++; - } - // Take ModuleIDs in same name block (firstly from right to left) - for (int N = L - 1; N >= 0; N--) { - ID = ConstOffsets[N].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - if (stricmp(ConstName, p + 4)) - break; - ModID = *((WORD*)p); - if (ModID != 0xFFFF && uses[num - 1] != ModID) { - uses[num] = ModID; - num++; - assert(num < ModuleCount); - } - } - // From left to right - for (int N = L + 1; N < ConstCount; N++) { - ID = ConstOffsets[N].NamId; - p = GetKBCachePtr(ConstOffsets[ID].Offset, ConstOffsets[ID].Size); - if (stricmp(ConstName, p + 4)) - break; - ModID = *((WORD*)p); - if (ModID != 0xFFFF && uses[num - 1] != ModID) { - uses[num] = ModID; - num++; - assert(num < ModuleCount); - } - } - // After last element must be word 0xFFFF - uses[num] = 0xFFFF; - return uses; - } - return 0; -} - -// --------------------------------------------------------------------------- -String __fastcall MKnowledgeBase::GetProcPrototype(int ProcIdx) { - MProcInfo pInfo; - if (Inited && GetProcInfo(ProcIdx, INFO_ARGS, &pInfo)) - return GetProcPrototype(&pInfo); - return ""; -} - -// --------------------------------------------------------------------------- -String __fastcall MKnowledgeBase::GetProcPrototype(MProcInfo* pInfo) { - String Result = ""; - - if (pInfo) { - switch (pInfo->MethodKind) { - case 'C': - Result += "constructor"; - break; - case 'D': - Result += "destructor"; - break; - case 'F': - Result += "function"; - break; - case 'P': - Result += "procedure"; - break; - } - if (Result != "") - Result += " "; - Result += pInfo->ProcName; - - if (pInfo->ArgsNum) - Result += "("; - - BYTE *p = pInfo->Args; - WORD Len; - for (int n = 0; n < pInfo->ArgsNum; n++) { - if (n) - Result += "; "; - // Tag - if (*p == 0x22) - Result += "var "; - p++; - // Register - p += 4; - // Ndx - p += 4; - // Name - Len = *((WORD*)p); - p += 2; - Result += String((char*)p, Len) + ":"; - p += Len + 1; - // TypeDef - Len = *((WORD*)p); - p += 2; - Result += String((char*)p, Len); - p += Len + 1; - } - if (pInfo->ArgsNum) - Result += ")"; - if (pInfo->MethodKind == 'F') { - Result += ":" + pInfo->TypeDef; - } - Result += ";"; - if (pInfo->CallKind) - Result += " "; - switch (pInfo->CallKind) { - case 1: - Result += "cdecl"; - break; - case 2: - Result += "pascal"; - break; - case 3: - Result += "stdcall"; - break; - case 4: - Result += "safecall"; - break; - } - if (pInfo->CallKind) - Result += ";"; - } - return Result; -} - -// --------------------------------------------------------------------------- -// as -// return direct pointer to const data of KB -const BYTE* __fastcall MKnowledgeBase::GetKBCachePtr(DWORD Offset, DWORD Size) { - assert(Offset >= 0 && Offset < SizeKBFile && (Offset + Size < SizeKBFile)); - return KBCache + Offset; -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::IsUsedProc(int AIdx) { - return (UsedProcs[AIdx] == 1); -} - -// --------------------------------------------------------------------------- -void __fastcall MKnowledgeBase::SetUsedProc(int AIdx) { - UsedProcs[AIdx] = 1; -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::GetKBProcInfo(String typeName, MProcInfo* procInfo, int* procIdx) { - int res, idx; - - res = (int)GetProcInfo(AnsiString(typeName).c_str(), INFO_DUMP | INFO_ARGS, procInfo, procIdx); - if (res && res != -1) { - return true; - } - return false; -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::GetKBTypeInfo(String typeName, MTypeInfo* typeInfo) { - int idx; - WORD *uses; - - uses = GetTypeUses(AnsiString(typeName).c_str()); - idx = GetTypeIdxByModuleIds(uses, AnsiString(typeName).c_str()); - if (uses) - delete[]uses; - if (idx != -1) { - idx = TypeOffsets[idx].NamId; - if (GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS /* | INFO_DUMP */ , typeInfo)) { - return true; - } - } - return false; -} - -// --------------------------------------------------------------------------- -bool __fastcall MKnowledgeBase::GetKBPropertyInfo(String className, String propName, MTypeInfo* typeInfo) { - int n, idx, pos; - BYTE *p; - WORD *uses, Len; - MTypeInfo tInfo; - String name, type; - - uses = GetTypeUses(AnsiString(className).c_str()); - idx = GetTypeIdxByModuleIds(uses, AnsiString(className).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = TypeOffsets[idx].NamId; - if (GetTypeInfo(idx, INFO_PROPS, &tInfo)) { - p = tInfo.Props; - for (n = 0; n < tInfo.PropsNum; n++) { - p++; // Scope - p += 4; // Index - p += 4; // DispID - Len = *((WORD*)p); - p += 2; - name = String((char*)p, Len); - p += Len + 1; // Name - Len = *((WORD*)p); - p += 2; - type = TrimTypeName(String((char*)p, Len)); - p += Len + 1; // TypeDef - Len = *((WORD*)p); - p += 2 + Len + 1; // ReadName - Len = *((WORD*)p); - p += 2 + Len + 1; // WriteName - Len = *((WORD*)p); - p += 2 + Len + 1; // StoredName - - if (SameText(name, propName)) { - pos = type.LastDelimiter(":."); - if (pos) - type = type.SubString(pos + 1, type.Length()); - return GetKBTypeInfo(type, typeInfo); - } - } - } - } - return false; -} - -// --------------------------------------------------------------------------- -String __fastcall MKnowledgeBase::IsPropFunction(String className, String procName) { - int n, idx; - BYTE *p; - WORD *uses, Len; - MTypeInfo tInfo; - String pname, type, fname; - - uses = GetTypeUses(AnsiString(className).c_str()); - idx = GetTypeIdxByModuleIds(uses, AnsiString(className).c_str()); - if (uses) - delete[]uses; - if (idx != -1) { - idx = TypeOffsets[idx].NamId; - if (GetTypeInfo(idx, INFO_PROPS, &tInfo)) { - p = tInfo.Props; - for (n = 0; n < tInfo.PropsNum; n++) { - p++; // Scope - p += 4; // Index - p += 4; // DispID - Len = *((WORD*)p); - p += 2; - pname = String((char*)p, Len); - p += Len + 1; // Name - Len = *((WORD*)p); - p += 2; - type = TrimTypeName(String((char*)p, Len)); - p += Len + 1; // TypeDef - Len = *((WORD*)p); - p += 2; - fname = TrimTypeName(String((char*)p, Len)); - p += Len + 1; // ReadName - if (SameText(procName, fname)) - return pname; - Len = *((WORD*)p); - p += 2; - fname = TrimTypeName(String((char*)p, Len)); - p += Len + 1; // WriteName - if (SameText(procName, fname)) - return pname; - Len = *((WORD*)p); - p += 2; - fname = TrimTypeName(String((char*)p, Len)); - p += Len + 1; // StoredName - if (SameText(procName, fname)) - return pname; - } - } - } - return ""; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/KnowledgeBase.h b/Sources/Libs/KnowledgeBase.h deleted file mode 100644 index 99b8c8c..0000000 --- a/Sources/Libs/KnowledgeBase.h +++ /dev/null @@ -1,379 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef KnowledgeBaseH -#define KnowledgeBaseH -// --------------------------------------------------------------------------- -#include -// --------------------------------------------------------------------------- -// Èíôîðìàöèÿ î ñìåùåíèÿõ èìåí è äàííûõ -typedef struct { - DWORD Offset; - DWORD Size; - int ModId; // Modules - int NamId; // Names -} OFFSETSINFO, *POFFSETSINFO; -// Fixup info -typedef struct { - BYTE Type; // 'A' - ADR, 'J' - JMP, 'D' - DAT - DWORD Ofs; // Ñìåùåíèå îòíîñèòåëüíî íà÷àëà äàìïà - char *Name; -} FIXUPINFO, *PFIXUPINFO; - -/* - ModuleDataTable - --------------- - //Ñîñòîèò èç ModuleCount çàïèñåé âèäà - WORD ID; - PSTR ModuleName; - PSTR Filename; - WORD UsesNum; - WORD UsesID[UsesNum]; //Ìàññèâ èäåíòèôèêàòîðîâ ìîäóëåé - PSTR UsesNames[UsesNum]; //Ìàññèâ èìåí ìîäóëåé - - ConstDataTable - -------------- - //Ñîñòîèò èç ModuleCount çàïèñåé âèäà - WORD ModuleID; - PSTR ConstName; - BYTE Type; //'C'-ConstDecl, 'P'-PDecl (VMT), 'V'-VarCDecl - PSTR TypeDef; //Òèï - PSTR Value; //Çíà÷åíèå - DWORD DumpTotal; //Îáùèé ðàçìåð äàìïà (äàìï+ðåëîêè+ôèêñàïû) - DWORD DumpSize; //Ðàçìåð áèíàðíîãî äàìïà (RTTI) - DWORD FixupNum; //Êîëè÷åñòâî ôèêñàïîâ äàìïà - BYTE Dump[DumpSize]; //Áèíàðíûé äàìï (RTTI) - BYTE Relocs[DumpSize]; - FIXUPINFO Fixups[FixupNum]; //Ìàññèâ ôèêñàïîâ - - TypeDataTable - ------------- - //Ñîñòîèò èç TypeCount çàïèñåé âèäà - DWORD Size; //Size of Type - WORD ModuleID; - PSTR TypeName; - BYTE Kind; //drArrayDef,...,drVariantDef (ñì. íà÷àëî) - DWORD VMCnt; //Êîëè÷åñòâî ýëåìåíòîâ VMT (íà÷èíàÿ ñ 0) - PSTR Decl; //Äåêëàðàöèÿ - DWORD DumpTotal; //Îáùèé ðàçìåð äàìïà (äàìï+ðåëîêè+ôèêñàïû) - DWORD DumpSize; //Ðàçìåð áèíàðíîãî äàìïà (RTTI) - DWORD FixupNum; //Êîëè÷åñòâî ôèêñàïîâ äàìïà - BYTE Dump[DumpSize]; //Áèíàðíûé äàìï (RTTI) - BYTE Relocs[DumpSize]; - FIXUPINFO Fixups[FixupNum]; //Ôèêñàïû - DWORD FieldsTotal; //Îáùèé ðàçìåð äàííûõ ïîëåé - WORD FieldsNum; //Êîëè÷åñòâî ïîëåé (class, interface, record) - FIELDINFO Fields[FieldNum]; //Ïîëÿ - DWORD PropsTotal; //Îáùèé ðàçìåð äàííûõ ñâîéñòâ - WORD PropsNum; //Êîëè÷åñòâî ñâîéñòâ (class, interface) - PROPERTYINFO Props[PropNum]; //Ñâîéñòâà - DWORD MethodsTotal; //Îáùèé ðàçìåð äàííûõ ìåòîäîâ - WORD MethodsNum; //Êîëè÷åñòâî ìåòîäîâ (class, interface) - METHODINFO Methods[MethodNum]; //Ìåòîäû - - VarDataTable - ------------ - //Ñîñòîèò èç VarCount çàïèñåé âèäà - WORD ModuleID; - PSTR VarName; - BYTE Type; //'V'-Var;'A'-AbsVar;'S'-SpecVar;'T'-ThreadVar - PSTR TypeDef; - PSTR AbsName; //Äëÿ êëþ÷åâîãî ñëîâà absolute - - ResStrDataTable - --------------- - //Ñîñòîèò èç ResStrCount çàïèñåé âèäà - WORD ModuleID; - PSTR ResStrName; - PSTR TypeDef; - PSTR Context; - - ProcDataTable - ------------- - //Contains ProcCount structures: - WORD ModuleID; - PSTR ProcName; - BYTE Embedded; //Contains embedded procs - BYTE DumpType; //'C' - code, 'D' - data - BYTE MethodKind; //'M'-method,'P'-procedure,'F'-function,'C'-constructor,'D'-destructor - BYTE CallKind; //1-'cdecl', 2-'pascal', 3-'stdcall', 4-'safecall' - int VProc; //Flag for "overload" (if Delphi version > verD3 and VProc&0x1000 != 0) - PSTR TypeDef; //Type of Result for function - DWORD DumpTotal; //Total size of dump (dump+relocs+fixups) - DWORD DumpSz; //Dump size - DWORD FixupNum; //Dump fixups number - BYTE Dump[DumpSz]; //Binary dump - BYTE Relocs[DumpSize]; - FIXUPINFO Fixups[FixupNum]; //Fixups - DWORD ArgsTotal; //Total size of arguments - WORD ArgsNum; //Arguments number - ARGINFO Args[ArgNum]; //Arguments - DWORD LocalsTotal; //Total size of local vars - WORD LocalsNum; //Local vars number - LOCALINFO Locals[LocalNum]; //Local vars - */ - -#define SCOPE_TMP 32 //Temp struct FIELDINFO, to be deleted - -typedef struct FIELDINFO { - FIELDINFO() : xrefs(0) { - } - ~FIELDINFO(); - - BYTE Scope; // 9-private, 10-protected, 11-public, 12-published - int Offset; // Offset in class instance - int Case; // Case for record (in other cases 0xFFFFFFFF) - String Name; // Field Name - String Type; // Field Type - TList *xrefs; // Xrefs from code -} FIELDINFO, *PFIELDINFO; - -typedef struct { - BYTE Scope; // 9-private, 10-protected, 11-public, 12-published - int Index; // readonly, writeonly â çàâèñèìîñòè îò óñòàíîâêè áèò 1 è 2 - int DispID; // ??? - String Name; // Èìÿ ñâîéñòâà - String TypeDef; // Òèï ñâîéñòâà - String ReadName; // Ïðîöåäóðà äëÿ ÷òåíèÿ ñâîéñòâà èëè ñîîòâåòñòâóþùåå ïîëå - String WriteName; // Ïðîöåäóðà äëÿ çàïèñè ñâîéñòâà èëè ñîîòâåòñòâóþùåå ïîëå - String StoredName; // Ïðîöåäóðà äëÿ ïðîâåðêè ñâîéñòâà èëè ñîîòâåòñòâóþùåå çíà÷åíèå -} PROPINFO, *PPROPINFO; - -typedef struct { - BYTE Scope; // 9-private, 10-protected, 11-public, 12-published - BYTE MethodKind; // 'M'-method, 'P'-procedure, 'F'-function, 'C'-constructor, 'D'-destructor - String Prototype; // Prototype full name -} METHODINFO, *PMETHODINFO; - -typedef struct { - BYTE Tag; // 0x21-"val", 0x22-"var" - bool Register; // If true - argument is in register, else - in stack - int Ndx; // Register number and offset (XX-number, XXXXXX-offset) (0-EAX, 1-ECX, 2-EDX) - int Size; // Argument Size - String Name; // Argument Name - String TypeDef; // Argument Type -} ARGINFO, *PARGINFO; - -typedef struct { - int Ofs; // Offset of local var (from ebp or EP) - int Size; // Size of local var - String Name; // Local var Name - String TypeDef; // Local var Type -} LOCALINFO, *PLOCALINFO; - -typedef struct { - char type; // 'C'-call; 'J'-jmp; 'D'-data - DWORD adr; // address of procedure - int offset; // offset in procedure -} XrefRec, *PXrefRec; - -// Ôëàæêè äëÿ çàïîëíåíèÿ ÷ëåíîâ êëàññîâ -#define INFO_DUMP 1 -#define INFO_ARGS 2 -#define INFO_LOCALS 4 -#define INFO_FIELDS 8 -#define INFO_PROPS 16 -#define INFO_METHODS 32 -#define INFO_ABSNAME 64 - -class MConstInfo { -public: - __fastcall MConstInfo(); - __fastcall ~MConstInfo(); - - WORD ModuleID; - String ConstName; - BYTE Type; // 'C'-ConstDecl, 'P'-PDecl (VMT), 'V'-VarCDecl - String TypeDef; // Òèï - String Value; // Çíà÷åíèå - DWORD DumpSz; // Ðàçìåð áèíàðíîãî äàìïà - DWORD FixupNum; // Êîëè÷åñòâî ôèêñàïîâ äàìïà - BYTE *Dump; // Áèíàðíûé äàìï -}; - -// Çíà÷åíèÿ áàéòà Kind èíôîðìàöèè î òèïå -#define drArrayDef 0x4C //'L' -#define drClassDef 0x46 //'F' -#define drFileDef 0x4F //'O' -#define drFloatDef 0x49 //'I' -#define drInterfaceDef 0x54 //'T' -#define drObjVMTDef 0x47 //'G' -#define drProcTypeDef 0x48 //'H' -#define drPtrDef 0x45 //'E' -#define drRangeDef 0x44 //'D' -#define drRecDef 0x4D //'M' -#define drSetDef 0x4A //'J' -#define drShortStrDef 0x4B //'K' -#define drStringDef 0x52 //'R' -#define drTextDef 0x50 //'P' -#define drVariantDef 0x53 //'S' -#define drAliasDef 0x41 //'Z' - -class MTypeInfo { -public: - __fastcall MTypeInfo(); - __fastcall ~MTypeInfo(); - - DWORD Size; - WORD ModuleID; - String TypeName; - BYTE Kind; // drArrayDef,...,drVariantDef - WORD VMCnt; // VMT elements number (from 0) - String Decl; // Declaration - DWORD DumpSz; // Binary dump size - DWORD FixupNum; // Binary dump fixup number - BYTE *Dump; // Binary dump - WORD FieldsNum; // Fields number (class, interface, record) - BYTE *Fields; - WORD PropsNum; // Properties number (class, interface) - BYTE *Props; - WORD MethodsNum; // Methods number (class, interface) - BYTE *Methods; -}; -// Var Type field -#define VT_VAR 'V' -#define VT_ABSVAR 'A' -#define VT_SPECVAR 'S' -#define VT_THREADVAR 'T' - -class MVarInfo { -public: - __fastcall MVarInfo(); - __fastcall ~MVarInfo(); - - WORD ModuleID; - String VarName; - BYTE Type; // 'V'-Var;'A'-AbsVar;'S'-SpecVar;'T'-ThreadVar - String TypeDef; - String AbsName; // Äëÿ êëþ÷åâîãî ñëîâà absolute -}; - -class MResStrInfo { -public: - __fastcall MResStrInfo(); - __fastcall ~MResStrInfo(); - - WORD ModuleID; - String ResStrName; - String TypeDef; - // String Context; -}; - -class MProcInfo { -public: - __fastcall MProcInfo(); - __fastcall ~MProcInfo(); - - WORD ModuleID; - String ProcName; - bool Embedded; // true-ñîäåðæèò âëîæåííûå ïðîöåäóðû - char DumpType; // 'C' - êîä, 'D' - äàííûå - char MethodKind; // 'M'-method,'P'-procedure,'F'-function,'C'-constructor,'D'-destructor - BYTE CallKind; // 1-'cdecl', 2-'pascal', 3-'stdcall', 4-'safecall' - int VProc; // ôëàæîê äëÿ "overload" (åñëè âåðñèÿ Äåëüôè > verD3 è VProc&0x1000 != 0) - String TypeDef; // Òèï - DWORD DumpSz; // Ðàçìåð áèíàðíîãî äàìïà - DWORD FixupNum; // Êîëè÷åñòâî ôèêñàïîâ äàìïà - BYTE *Dump; // Áèíàðíûé äàìï (âêëþ÷àåò â ñåáÿ ñîáñòâåííî äàìï, ðåëîêè è ôèêñàïû) - WORD ArgsNum; // Êîëè÷åñòâî àðãóìåíòîâ ïðîöåäóðû - BYTE *Args; // Ñïèñîê àðãóìåíòîâ - // WORD LocalsNum; //Êîëè÷åñòâî ëîêàëüíûõ ïåðåìåííûõ ïðîöåäóðû - // BYTE *Locals; //Ñïèñîê ëîêàëüíûõ ïåðåìåííûõ -}; -// Ñåêöèè áàçû çíàíèé -#define KB_NO_SECTION 0 -#define KB_CONST_SECTION 1 -#define KB_TYPE_SECTION 2 -#define KB_VAR_SECTION 4 -#define KB_RESSTR_SECTION 8 -#define KB_PROC_SECTION 16 - -class MKnowledgeBase { -public: - __fastcall MKnowledgeBase(); - __fastcall ~MKnowledgeBase(); - - bool __fastcall Open(char* filename); - void __fastcall Close(); - - const BYTE* __fastcall GetKBCachePtr(DWORD Offset, DWORD Size); - WORD __fastcall GetModuleID(char* ModuleName); - String __fastcall GetModuleName(WORD ModuleID); - void __fastcall GetModuleIdsByProcName(char* ProcName); - int __fastcall GetItemSection(WORD* ModuleIDs, char* ItemName); - int __fastcall GetConstIdx(WORD* ModuleID, char* ConstName); - int __fastcall GetConstIdxs(char* ConstName, int* ConstIdx); - int __fastcall GetTypeIdxByModuleIds(WORD* ModuleIDs, char* TypeName); - int __fastcall GetTypeIdxsByName(char* TypeName, int* TypeIdx); - int __fastcall GetTypeIdxByUID(char* UID); - int __fastcall GetVarIdx(WORD* ModuleIDs, char* VarName); - int __fastcall GetResStrIdx(int from, char* ResStrContext); - int __fastcall GetResStrIdx(WORD ModuleID, char* ResStrContext); - int __fastcall GetResStrIdx(WORD* ModuleIDs, char* ResStrName); - int __fastcall GetProcIdx(WORD ModuleID, char* ProcName); - int __fastcall GetProcIdx(WORD ModuleID, char* ProcName, BYTE* code); - int __fastcall GetProcIdx(WORD* ModuleIDs, char* ProcName, BYTE* code); - bool __fastcall GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx); - bool __fastcall GetProcIdxs(WORD ModuleID, int* FirstProcIdx, int* LastProcIdx, int* DumpSize); - MConstInfo* __fastcall GetConstInfo(int AConstIdx, DWORD AFlags, MConstInfo* cInfo); - MProcInfo* __fastcall GetProcInfo(char* ProcName, DWORD AFlags, MProcInfo* pInfo, int* procIdx); - MProcInfo* __fastcall GetProcInfo(int AProcIdx, DWORD AFlags, MProcInfo* pInfo); - MTypeInfo* __fastcall GetTypeInfo(int ATypeIdx, DWORD AFlags, MTypeInfo* tInfo); - MVarInfo* __fastcall GetVarInfo(int AVarIdx, DWORD AFlags, MVarInfo* vInfo); - MResStrInfo* __fastcall GetResStrInfo(int AResStrIdx, DWORD AFlags, MResStrInfo* rsInfo); - int __fastcall ScanCode(BYTE* code, DWORD* CodeFlags, DWORD CodeSz, MProcInfo* pInfo); - WORD* __fastcall GetModuleUses(WORD ModuleID); - int __fastcall GetProcUses(char* ProcName, WORD* uses); - WORD* __fastcall GetTypeUses(char* TypeName); - WORD* __fastcall GetConstUses(char* ConstName); - String __fastcall GetProcPrototype(int ProcIdx); - String __fastcall GetProcPrototype(MProcInfo* pInfo); - bool __fastcall IsUsedProc(int AIdx); - void __fastcall SetUsedProc(int AIdx); - bool __fastcall GetKBProcInfo(String typeName, MProcInfo* procInfo, int* procIdx); - bool __fastcall GetKBTypeInfo(String typeName, MTypeInfo* typeInfo); - bool __fastcall GetKBPropertyInfo(String className, String propName, MTypeInfo* typeInfo); - String __fastcall IsPropFunction(String className, String procName); - - DWORD Version; - int ModuleCount; - OFFSETSINFO *ModuleOffsets; - WORD *Mods; - BYTE *UsedProcs; - const OFFSETSINFO *ConstOffsets; - const OFFSETSINFO *TypeOffsets; - const OFFSETSINFO *VarOffsets; - const OFFSETSINFO *ResStrOffsets; - const OFFSETSINFO *ProcOffsets; - -private: - bool Inited; - FILE *Handle; - - bool __fastcall CheckKBFile(); - - long SectionsOffset; - // Modules - int MaxModuleDataSize; - // Consts - int ConstCount; - int MaxConstDataSize; - // Types - int TypeCount; - int MaxTypeDataSize; - // Vars - int VarCount; - int MaxVarDataSize; - // ResStr - int ResStrCount; - int MaxResStrDataSize; - // Procs - int MaxProcDataSize; - int ProcCount; - - // as temp test (global KB file cache in mem) - const BYTE *KBCache; - long SizeKBFile; - String NameKBFile; - -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Misc.cpp b/Sources/Libs/Misc.cpp deleted file mode 100644 index 5d202f5..0000000 --- a/Sources/Libs/Misc.cpp +++ /dev/null @@ -1,4124 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include -#include -/* - #include - #include - #include "assert.h" - */ - -#include "Misc.h" -#include "InputDlg.h" -// --------------------------------------------------------------------------- -extern int dummy; -extern String IDRVersion; -extern String SelectedAsmItem; -extern char StringBuf[MAXSTRBUFFER]; -extern DWORD ImageBase; -extern DWORD ImageSize; -extern DWORD TotalSize; -extern DWORD CodeBase; -extern DWORD CodeSize; -extern DWORD DataBase; -extern DWORD *Flags; -extern PInfoRec *Infos; -extern TStringList *BSSInfos; -extern MDisasm Disasm; -extern MKnowledgeBase KnowledgeBase; -extern BYTE *Code; -extern int DelphiVersion; -extern TList *SegmentList; -extern TList *OwnTypeList; -extern TList *VmtList; -extern int VmtSelfPtr; -extern int VmtIntfTable; -extern int VmtInitTable; -extern int VmtParent; -extern int VmtClassName; -extern int VmtInstanceSize; -extern char* Reg8Tab[8]; -extern char* Reg16Tab[8]; -extern char* Reg32Tab[8]; -extern char* SegRegTab[8]; - -// --------------------------------------------------------------------------- -void __fastcall ScaleForm(TForm* AForm) { - HDC _hdc = GetDC(0); - if (_hdc) { - AForm->ScaleBy(GetDeviceCaps(_hdc, 0x58), 100); - ReleaseDC(0, _hdc); - } -} - -// --------------------------------------------------------------------------- -int __fastcall Adr2Pos(DWORD adr) { - int ofs = 0; - for (int n = 0; n < SegmentList->Count; n++) { - PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; - if (segInfo->Start <= adr && adr < segInfo->Start + segInfo->Size) { - if (segInfo->Flags & 0x80000) - return -1; - return ofs + (adr - segInfo->Start); - } - if (!(segInfo->Flags & 0x80000)) - ofs += segInfo->Size; - } - return -2; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall Pos2Adr(int Pos) { - int fromPos = 0; - int toPos = 0; - for (int n = 0; n < SegmentList->Count; n++) { - PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; - if (!(segInfo->Flags & 0x80000)) { - fromPos = toPos; - toPos += segInfo->Size; - if (fromPos <= Pos && Pos < toPos) - return segInfo->Start + (Pos - fromPos); - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// Can replace type "fromName" to type "toName"? -bool __fastcall CanReplace(const String& fromName, const String& toName) { - // Skip empty toName - if (toName == "") - return false; - // We can replace empty "fromName" or name "byte", "word", "dword' - if (fromName == "" || SameText(fromName, "byte") || SameText(fromName, "word") || SameText(fromName, "dword")) - return true; - return false; -} - -// --------------------------------------------------------------------------- -String __fastcall GetDefaultProcName(DWORD adr) { - return "sub_" + Val2Str8(adr); -} - -// --------------------------------------------------------------------------- -String __fastcall Val2Str0(DWORD Val) { - return IntToHex((int)Val, 0); -} - -// --------------------------------------------------------------------------- -String __fastcall Val2Str1(DWORD Val) { - return IntToHex((int)Val, 1); -} - -// --------------------------------------------------------------------------- -String __fastcall Val2Str2(DWORD Val) { - return IntToHex((int)Val, 2); -} - -// --------------------------------------------------------------------------- -String __fastcall Val2Str4(DWORD Val) { - return IntToHex((int)Val, 4); -} - -// --------------------------------------------------------------------------- -String __fastcall Val2Str5(DWORD Val) { - return IntToHex((int)Val, 5); -} - -// --------------------------------------------------------------------------- -String __fastcall Val2Str8(DWORD Val) { - return IntToHex((int)Val, 8); -} - -// --------------------------------------------------------------------------- -PInfoRec __fastcall AddToBSSInfos(DWORD Adr, String AName, String ATypeName) { - PInfoRec recN; - String _key = Val2Str8(Adr); - int _idx = BSSInfos->IndexOf(_key); - if (_idx == -1) { - recN = new InfoRec(-1, ikData); - recN->SetName(AName); - recN->type = ATypeName; - BSSInfos->AddObject(_key, (TObject*)recN); - } - else { - recN = (PInfoRec)BSSInfos->Objects[_idx]; - if (recN->type == "") { - recN->type = ATypeName; - } - } - return recN; -} - -// --------------------------------------------------------------------------- -String __fastcall MakeGvarName(DWORD adr) { - return "gvar_" + Val2Str8(adr); -} - -// --------------------------------------------------------------------------- -void __fastcall MakeGvar(PInfoRec recN, DWORD adr, DWORD xrefAdr) { - if (!recN->HasName()) - recN->SetName(MakeGvarName(adr)); - if (xrefAdr) - recN->AddXref('C', xrefAdr, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall FillArgInfo(int k, BYTE callkind, PARGINFO argInfo, BYTE** p, int* s) { - BYTE* pp = *p; - int ss = *s; - argInfo->Tag = *pp; - pp++; - int locflags = *((int*)pp); - pp += 4; - - if ((locflags & 7) == 1) - argInfo->Tag = 0x23; // Add by ZGL - - argInfo->Register = (locflags & 8); - int ndx = *((int*)pp); - pp += 4; - - // fastcall - if (!callkind) { - if (argInfo->Register && k < 3) { - argInfo->Ndx = k; // << 24;??? - } - else { - argInfo->Ndx = ndx; - } - } - // stdcall, cdecl, pascal - else { - argInfo->Ndx = ss; - ss += 4; - } - - argInfo->Size = 4; - WORD wlen = *((WORD*)pp); - pp += 2; - argInfo->Name = String((char*)pp, wlen); - pp += wlen + 1; - wlen = *((WORD*)pp); - pp += 2; - argInfo->TypeDef = TrimTypeName(String((char*)pp, wlen)); - pp += wlen + 1; - *p = pp; - *s = ss; -} - -// --------------------------------------------------------------------------- -String __fastcall TrimTypeName(const String& TypeName) { - if (TypeName.IsEmpty()) - return TypeName; - int pos = TypeName.Pos("."); - // No '.' in TypeName or TypeName begins with '.' - if (pos == 0 || pos == 1) - return TypeName; - // èëè ýòî èìÿ òèïà range - else if (TypeName[pos + 1] == '.') - return TypeName; - else { - char c, *p = AnsiString(TypeName.c_str()).c_str(); - // Check special symbols upto '.' - while (1 && TypeName.Length()) { - c = *p++; - if (c == '.') - break; - if (c < '0' || c == '<') - return TypeName; - } - return ExtractProcName(TypeName); - } -} - -// --------------------------------------------------------------------------- -bool __fastcall IsValidImageAdr(DWORD Adr) { - if (Adr >= CodeBase && Adr < CodeBase + ImageSize) - return true; - else - return false; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsValidCodeAdr(DWORD Adr) { - if (Adr >= CodeBase && Adr < CodeBase + CodeSize) - return true; - else - return false; -} - -// --------------------------------------------------------------------------- -String __fastcall ExtractClassName(const String& AName) { - if (AName == "") - return ""; - int pos = AName.Pos("."); - if (pos) - return AName.SubString(1, pos - 1); - else - return ""; -} - -// --------------------------------------------------------------------------- -String __fastcall ExtractProcName(const String& AName) { - if (AName == "") - return ""; - int pos = AName.Pos("."); - if (pos) - return AName.SubString(pos + 1, AName.Length()); - else - return AName; -} - -// --------------------------------------------------------------------------- -String __fastcall ExtractName(const String& AName) { - if (AName == "") - return ""; - int _pos = AName.Pos(":"); - if (_pos) - return AName.SubString(1, _pos - 1); - else - return AName; -} - -// --------------------------------------------------------------------------- -String __fastcall ExtractType(const String& AName) { - if (AName == "") - return ""; - int _pos = AName.Pos(":"); - if (_pos) - return AName.SubString(_pos + 1, AName.Length()); - else - return ""; -} - -// --------------------------------------------------------------------------- -// Return position of nearest up argument eax from position fromPos -int __fastcall GetNearestArgA(int fromPos) { - int curPos = fromPos; - - for (curPos = fromPos - 1; ; curPos--) { - if (IsFlagSet(cfInstruction, curPos)) { - if (IsFlagSet(cfProcStart, curPos)) - break; - if (IsFlagSet(cfSetA, curPos)) - return curPos; - } - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of nearest up instruction with segment prefix fs: -int __fastcall GetNearestUpPrefixFs(int fromPos) { - int _pos; - DISINFO _disInfo; - - assert(fromPos >= 0); - for (_pos = fromPos - 1; _pos >= 0; _pos--) { - if (IsFlagSet(cfInstruction, _pos)) { - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - if (_disInfo.SegPrefix == 4) - return _pos; - } - if (IsFlagSet(cfProcStart, _pos)) - break; - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of nearest up instruction from position fromPos -int __fastcall GetNearestUpInstruction(int fromPos) { - assert(fromPos >= 0); - for (int pos = fromPos - 1; pos >= 0; pos--) { - if (IsFlagSet(cfInstruction, pos)) - return pos; - if (IsFlagSet(cfProcStart, pos)) - break; - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of N-th up instruction from position fromPos -int __fastcall GetNthUpInstruction(int fromPos, int N) { - if (fromPos < 0) - return -1; - assert(fromPos >= 0); - for (int pos = fromPos - 1; pos >= 0; pos--) { - if (IsFlagSet(cfInstruction, pos)) { - N--; - if (!N) - return pos; - } - if (IsFlagSet(cfProcStart, pos)) - break; - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of nearest up instruction from position fromPos -int __fastcall GetNearestUpInstruction(int fromPos, int toPos) { - assert(fromPos >= 0); - for (int pos = fromPos - 1; pos >= toPos; pos--) { - if (IsFlagSet(cfInstruction, pos)) - return pos; - if (IsFlagSet(cfProcStart, pos)) - break; - } - return -1; -} - -// --------------------------------------------------------------------------- -int __fastcall GetNearestUpInstruction(int fromPos, int toPos, int no) { - assert(fromPos >= 0); - for (int pos = fromPos - 1; pos >= toPos; pos--) { - if (IsFlagSet(cfInstruction, pos)) { - no--; - if (!no) - return pos; - } - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of nearest up instruction from position fromPos -int __fastcall GetNearestUpInstruction1(int fromPos, int toPos, char* Instruction) { - int len = strlen(Instruction); - int pos; - DISINFO DisInfo; - - assert(fromPos >= 0); - for (pos = fromPos - 1; pos >= toPos; pos--) { - if (IsFlagSet(cfInstruction, pos)) { - Disasm.Disassemble(Pos2Adr(pos), &DisInfo, 0); - if (len && !memicmp(DisInfo.Mnem, Instruction, len)) - return pos; - } - if (IsFlagSet(cfProcStart, pos)) - break; - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of nearest up instruction from position fromPos -int __fastcall GetNearestUpInstruction2(int fromPos, int toPos, char* Instruction1, char* Instruction2) { - int len1 = strlen(Instruction1), len2 = strlen(Instruction2); - int pos; - DISINFO DisInfo; - - assert(fromPos >= 0); - for (pos = fromPos - 1; pos >= toPos; pos--) { - if (IsFlagSet(cfInstruction, pos)) { - Disasm.Disassemble(Pos2Adr(pos), &DisInfo, 0); - if ((len1 && !memicmp(DisInfo.Mnem, Instruction1, len1)) || (len2 && !memicmp(DisInfo.Mnem, Instruction2, len2))) - return pos; - } - if (IsFlagSet(cfProcStart, pos)) - break; - } - return -1; -} - -// --------------------------------------------------------------------------- -// Return position of nearest down instruction from position fromPos -int __fastcall GetNearestDownInstruction(int fromPos) { - int instrLen; - DISINFO DisInfo; - - assert(fromPos >= 0); - instrLen = Disasm.Disassemble(Pos2Adr(fromPos), &DisInfo, 0); - if (!instrLen) - return -1; - return fromPos + instrLen; -} - -// --------------------------------------------------------------------------- -// Return position of nearest down "Instruction" from position fromPos -int __fastcall GetNearestDownInstruction(int fromPos, char* Instruction) { - int instrLen, len = strlen(Instruction); - int curPos = fromPos; - DISINFO DisInfo; - - assert(fromPos >= 0); - while (1) { - instrLen = Disasm.Disassemble(Pos2Adr(curPos), &DisInfo, 0); - if (!instrLen) { - curPos++; - continue; - } - if (len && !memcmp(DisInfo.Mnem, Instruction, len)) - return curPos; - if (DisInfo.Ret) - break; - curPos += instrLen; - } - return -1; -} - -// --------------------------------------------------------------------------- -// -1 - error -// 0 - simple if -// 1 - jcc down -// 2 - jcc up -// 3 - jmp down -// 4 - jump up -int __fastcall BranchGetPrevInstructionType(DWORD fromAdr, DWORD* jmpAdr, PLoopInfo loopInfo) { - int _pos; - DISINFO _disInfo; - - *jmpAdr = 0; - _pos = GetNearestUpInstruction(Adr2Pos(fromAdr)); - if (_pos == -1) - return -1; - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - if (_disInfo.Branch) { - if (IsExit(_disInfo.Immediate)) - return 0; - if (_disInfo.Conditional) { - if (_disInfo.Immediate > CodeBase + _pos) { - if (loopInfo && loopInfo->BreakAdr == _disInfo.Immediate) - return 0; - return 1; - } - return 2; - } - if (_disInfo.Immediate > CodeBase + _pos) { - *jmpAdr = _disInfo.Immediate; - return 3; - } - // jmp after jmp @HandleFinally - if (IsFlagSet(cfFinally, _pos)) { - _pos = GetNearestUpInstruction(Adr2Pos(_disInfo.Immediate)); - // push Adr - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - if (_disInfo.Immediate == fromAdr) - return 0; - *jmpAdr = _disInfo.Immediate; - return 3; - } - return 4; - } - return 0; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsFlagSet(DWORD flag, int pos) { - // !!! - if (pos < 0 || pos >= TotalSize) { - dummy = 1; - return false; - } - assert(pos >= 0 && pos < TotalSize); - return (Flags[pos] & flag); -} - -// --------------------------------------------------------------------------- -void __fastcall SetFlag(DWORD flag, int pos) { - // !!! - if (pos < 0 || pos >= TotalSize) { - dummy = 1; - return; - } - assert(pos >= 0 && pos < TotalSize); - Flags[pos] |= flag; -} - -// --------------------------------------------------------------------------- -void __fastcall SetFlags(DWORD flag, int pos, int num) { - // !!! - if (pos < 0 || pos + num >= TotalSize) { - dummy = 1; - return; - } - assert(pos >= 0 && pos + num < TotalSize); - for (int i = pos; i < pos + num; i++) { - Flags[i] |= flag; - } -} - -// --------------------------------------------------------------------------- -void __fastcall ClearFlag(DWORD flag, int pos) { - // !!! - if (pos < 0 || pos >= TotalSize) { - dummy = 1; - return; - } - assert(pos >= 0 && pos < TotalSize); - Flags[pos] &= ~flag; -} - -// --------------------------------------------------------------------------- -void __fastcall ClearFlags(DWORD flag, int pos, int num) { - if (pos < 0 || pos + num > TotalSize) { - dummy = 1; - return; - } - assert(pos >= 0 && pos + num <= TotalSize); - for (int i = pos; i < pos + num; i++) { - Flags[i] &= ~flag; - } -} - -// --------------------------------------------------------------------------- -// pInfo must contain pInfo-> -int __fastcall GetProcRetBytes(MProcInfo* pInfo) { - int _pos = pInfo->DumpSz - 1; - DWORD _curAdr = CodeBase + _pos; - DISINFO _disInfo; - - while (_pos >= 0) { - Disasm.Disassemble(pInfo->Dump + _pos, (__int64)_curAdr, &_disInfo, 0); - if (_disInfo.Ret) { - if (_disInfo.OpType[0] == otIMM) // ImmPresent) - return _disInfo.Immediate; - else - return 0; - } - _pos--; - _curAdr--; - } - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall GetProcSize(DWORD fromAdr) { - int _size = 0; - PInfoRec recN = GetInfoRec(fromAdr); - if (recN && recN->procInfo) - _size = recN->procInfo->procSize; - if (!_size) - _size = FMain_11011981->EstimateProcSize(fromAdr); - return _size; - /* - int pos, size = 0; - for (pos = Adr2Pos(fromAdr); pos < TotalSize; pos++) - { - size++; - if (IsFlagSet(cfProcEnd, pos)) break; - } - return size; - */ -} - -// --------------------------------------------------------------------------- -int __fastcall GetRecordSize(String AName) { - BYTE _len; - WORD *_uses; - int _idx, _pos, _size; - MTypeInfo _tInfo; - PTypeRec _recT; - String _str; - - // File - AnsiString _recFileName = FMain_11011981->WrkDir + "\\types.idr"; - FILE* _recFile = fopen(_recFileName.c_str(), "rt"); - if (_recFile) { - while (1) { - if (!fgets(StringBuf, 1024, _recFile)) - break; - _str = String(StringBuf); - if (_str.Pos(AName + "=") == 1) { - _pos = _str.Pos("size="); - if (_pos) { - sscanf(StringBuf + _pos + 4, "%lX", &_size); - fclose(_recFile); - return _size; - } - } - } - fclose(_recFile); - } - // KB - _uses = KnowledgeBase.GetTypeUses(AnsiString(AName).c_str()); - _idx = KnowledgeBase.GetTypeIdxByModuleIds(_uses, AnsiString(AName).c_str()); - if (_uses) - delete[]_uses; - - if (_idx != -1) { - _idx = KnowledgeBase.TypeOffsets[_idx].NamId; - if (KnowledgeBase.GetTypeInfo(_idx, INFO_DUMP, &_tInfo)) - return _tInfo.Size; - } - // RTTI - _recT = GetOwnTypeByName(AName); - if (_recT && _recT->kind == ikRecord) { - _pos = Adr2Pos(_recT->adr); - _pos += 4; // SelfPtr - _pos++; // TypeKind - _len = Code[_pos]; - _pos += _len + 1; // Name - return *((DWORD*)(Code + _pos)); - } - // Manual - return 0; -} - -// --------------------------------------------------------------------------- -String __fastcall GetRecordFields(int AOfs, String ARecType) { - BYTE _len, _numOps, _kind; - char *p; - WORD _dw, _len1; - WORD *_uses; - int i, k, _idx, _pos, _elNum, _elOfs, _size, _case, _offset; - DWORD _typeAdr; - PTypeRec _recT; - MTypeInfo _tInfo; - String _str, _name, _typeName, _result = ""; - - if (ARecType == "") - return _result; - - _pos = ARecType.Pos("."); - if (_pos > 1 && ARecType[_pos + 1] != ':') - ARecType = ARecType.SubString(_pos + 1, ARecType.Length()); - - // File - AnsiString _recFileName = FMain_11011981->WrkDir + "\\types.idr"; - FILE* _recFile = fopen(_recFileName.c_str(), "rt"); - if (_recFile) { - while (1) { - if (!fgets(StringBuf, 1024, _recFile)) - break; - _str = String(StringBuf); - if (_str.Pos(ARecType + "=") == 1) { - while (1) { - if (!fgets(StringBuf, 1024, _recFile)) - break; - _str = String(StringBuf); - if (_str.Pos("end;")) - break; - if (_str.Pos("//" + Val2Str0(AOfs))) { - _result = _str; - _pos = _result.LastDelimiter(";"); - if (_pos) - _result.SetLength(_pos - 1); - fclose(_recFile); - return _result; - } - } - } - } - fclose(_recFile); - } - - int tries = 5; - while (tries-- >= 0) { - // KB - _uses = KnowledgeBase.GetTypeUses(AnsiString(ARecType).c_str()); - _idx = KnowledgeBase.GetTypeIdxByModuleIds(_uses, AnsiString(ARecType).c_str()); - if (_uses) - delete[]_uses; - - if (_idx != -1) { - _idx = KnowledgeBase.TypeOffsets[_idx].NamId; - if (KnowledgeBase.GetTypeInfo(_idx, INFO_FIELDS, &_tInfo)) { - if (_tInfo.FieldsNum) { - p = (char*)_tInfo.Fields; - for (k = 0; k < _tInfo.FieldsNum; k++) { - // Scope - p++; - _offset = *((int*)p); - p += 4; - _case = *((int*)p); - p += 4; - // Name - _len1 = *((WORD*)p); - p += 2; - _name = String((char*)p, _len1); - p += _len1 + 1; - // Type - _len1 = *((WORD*)p); - p += 2; - _typeName = TrimTypeName(String((char*)p, _len1)); - p += _len1 + 1; - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _size = GetRecordSize(_typeName); - if (AOfs >= _offset && AOfs < _offset + _size) - _result += _name + "." + GetRecordFields(AOfs - _offset, _typeName); - } - else if (AOfs >= _offset && AOfs < _offset + _size) { - if (_size > 4) - _result = _name + "+" + String(AOfs - _elOfs) + ":" + _typeName; - else - _result = _name + ":" + _typeName; - } - if (_result != "") - return _result; - } - } - else if (_tInfo.Decl != "") { - ARecType = _tInfo.Decl; - // _result = GetRecordFields(AOfs, _tInfo.Decl); - } - } - } - } - // if (_result != "") return _result; - // RTTI - _recT = GetOwnTypeByName(ARecType); - if (_recT && _recT->kind == ikRecord) { - _pos = Adr2Pos(_recT->adr); - _pos += 4; // SelfPtr - _pos++; // TypeKind - _len = Code[_pos]; - _pos += _len + 1; // Name - _pos += 4; // Size - _elNum = *((DWORD*)(Code + _pos)); - _pos += 4; - for (i = 0; i < _elNum; i++) { - _typeAdr = *((DWORD*)(Code + _pos)); - _pos += 4; - _elOfs = *((DWORD*)(Code + _pos)); - _pos += 4; - _typeName = GetTypeName(_typeAdr); - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _size = GetRecordSize(_typeName); - if (AOfs >= _elOfs && AOfs < _elOfs + _size) - _result = "f" + Val2Str0(_elOfs) + "." + GetRecordFields(AOfs - _elOfs, _typeName); - } - else if (AOfs >= _elOfs && AOfs < _elOfs + _size) { - if (_size > 4) - _result = "f" + Val2Str0(_elOfs) + "+" + String(AOfs - _elOfs) + ":" + _typeName; - else - _result = "f" + Val2Str0(_elOfs) + ":" + _typeName; - } - } - if (DelphiVersion >= 2010) { - // NumOps - _numOps = Code[_pos]; - _pos++; - for (i = 0; i < _numOps; i++) // RecOps - { - _pos += 4; - } - _elNum = *((DWORD*)(Code + _pos)); - _pos += 4; // RecFldCnt - - for (i = 0; i < _elNum; i++) { - // TypeRef - _typeAdr = *((DWORD*)(Code + _pos)); - _pos += 4; - // FldOffset - _elOfs = *((DWORD*)(Code + _pos)); - _pos += 4; - // Flags - _pos++; - // Name - _len = Code[_pos]; - _pos++; - _name = String((char*)(Code + _pos), _len); - _pos += _len; - _typeName = GetTypeName(_typeAdr); - _kind = GetTypeKind(_typeName, &_size); - if (_kind == ikRecord) { - _size = GetRecordSize(_typeName); - if (AOfs >= _elOfs && AOfs < _elOfs + _size) - _result = _name + "." + GetRecordFields(AOfs - _elOfs, _typeName); - } - else if (AOfs >= _elOfs && AOfs < _elOfs + _size) { - if (_size > 4) - _result = _name + "+" + String(AOfs - _elOfs) + ":" + _typeName; - else - _result = _name + ":" + _typeName; - } - // AttrData - _dw = *((WORD*)(Code + _pos)); - _pos += _dw; // ATR!! - } - } - } - return _result; -} - -// --------------------------------------------------------------------------- -String __fastcall GetAsmRegisterName(int Idx) { - assert(Idx >= 0 && Idx < 32); - if (Idx >= 31) - return "st(" + String(Idx - 31) + ")"; - if (Idx == 30) - return "st"; - if (Idx >= 24) - return String(SegRegTab[Idx - 24]); - if (Idx >= 16) - return String(Reg32Tab[Idx - 16]); - if (Idx >= 8) - return String(Reg16Tab[Idx - 8]); - return String(Reg8Tab[Idx]); -} - -// --------------------------------------------------------------------------- -String __fastcall GetDecompilerRegisterName(int Idx) { - assert(Idx >= 0 && Idx < 32); - if (Idx >= 16) - return UpperCase(Reg32Tab[Idx - 16]); - if (Idx >= 8) - return UpperCase(Reg32Tab[Idx - 8]); - return UpperCase(Reg32Tab[Idx]); -} - -// --------------------------------------------------------------------------- -bool __fastcall IsValidModuleName(int len, int pos) { - if (!len) - return false; - for (int i = pos; i < pos + len; i++) { - BYTE b = *(Code + i); - if (b < ' ' || b == ':' || (b & 0x80)) - return false; - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsValidName(int len, int pos) { - if (!len) - return false; - for (int i = pos; i < pos + len; i++) { - // if (IsFlagSet(cfCode, i)) return false; - - BYTE b = *(Code + i); - // first symbol may be letter or '_' or '.' or ':' - if (i == pos) { - if ((b >= 'A' && b <= 'z') || b == '.' || b == '_' || b == ':') - continue; - else - return false; - } - if (b & 0x80) - return false; - // if ((b < '0' || b > 'z') && b != '.' && b != '_' && b != ':' && b != '$') return false; - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsValidString(int len, int pos) { - if (len < 5) - return false; - for (int i = pos; i < pos + len; i++) { - // if (IsFlagSet(cfCode, i)) return false; - - BYTE b = *(Code + i); - if (b < ' ' && b != '\t' && b != '\n' && b != '\r') - return false; - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsValidCString(int pos) { - int len = 0; - for (int i = pos; i < pos + 1024; i++) { - BYTE b = *(Code + i); - // if (IsFlagSet(cfCode, i)) break; - if (!b) - return (len >= 5); - if (b < ' ' && b != '\t' && b != '\n' && b != '\r') - break; - len++; - } - return false; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall GetParentAdr(DWORD Adr) { - if (!IsValidImageAdr(Adr)) - return 0; - - DWORD vmtAdr = Adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtParent; - DWORD adr = *((DWORD*)(Code + pos)); - if (IsValidImageAdr(adr) && IsFlagSet(cfImport, Adr2Pos(adr))) - return 0; - - if (DelphiVersion == 2 && adr) - adr += VmtSelfPtr; - return adr; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall GetChildAdr(DWORD Adr) { - if (!IsValidImageAdr(Adr)) - return 0; - for (int m = 0; m < VmtList->Count; m++) { - PVmtListRec recV = (PVmtListRec)VmtList->Items[m]; - if (recV->vmtAdr != Adr && IsInheritsByAdr(recV->vmtAdr, Adr)) - return recV->vmtAdr; - } - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall GetClassSize(DWORD adr) { - if (!IsValidImageAdr(adr)) - return 0; - - DWORD vmtAdr = adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtInstanceSize; - int size = *((int*)(Code + pos)); - if (DelphiVersion >= 2009) - return size - 4; - return size; -} - -// --------------------------------------------------------------------------- -String __fastcall GetClsName(DWORD adr) { - if (!IsValidImageAdr(adr)) - return ""; - - DWORD vmtAdr = adr - VmtSelfPtr; - DWORD pos = Adr2Pos(vmtAdr) + VmtClassName; - if (IsFlagSet(cfImport, pos)) { - PInfoRec recN = GetInfoRec(vmtAdr + VmtClassName); - return recN->GetName(); - } - DWORD nameAdr = *((DWORD*)(Code + pos)); - if (!IsValidImageAdr(nameAdr)) - return ""; - - pos = Adr2Pos(nameAdr); - BYTE len = Code[pos]; - pos++; - return String((char*)&Code[pos], len); -} - -// --------------------------------------------------------------------------- -DWORD __fastcall GetClassAdr(const String& AName) { - String name; - - if (AName.IsEmpty()) - return 0; - - DWORD adr = FindClassAdrByName(AName); - if (adr) - return adr; - - int pos = AName.Pos("."); - if (pos) { - // type as .XX or array[XX..XX] of XXX - skip - if (pos == 1 || AName[pos + 1] == '.') - return 0; - name = AName.SubString(pos + 1, AName.Length()); - } - else - name = AName; - - const int vmtCnt = VmtList->Count; - for (int n = 0; n < vmtCnt; n++) { - PVmtListRec recV = (PVmtListRec)VmtList->Items[n]; - if (SameText(recV->vmtName, name)) { - adr = recV->vmtAdr; - AddClassAdr(adr, name); - return adr; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall GetParentSize(DWORD Adr) { - return GetClassSize(GetParentAdr(Adr)); -} - -// --------------------------------------------------------------------------- -String __fastcall GetParentName(DWORD Adr) { - DWORD adr = GetParentAdr(Adr); - if (!adr) - return ""; - return GetClsName(adr); -} - -// --------------------------------------------------------------------------- -String __fastcall GetParentName(const String& ClassName) { - return GetParentName(GetClassAdr(ClassName)); -} - -// --------------------------------------------------------------------------- -// Adr1 inherits Adr2 (Adr1 >= Adr2) -bool __fastcall IsInheritsByAdr(const DWORD Adr1, const DWORD Adr2) { - DWORD adr = Adr1; - while (adr) { - if (adr == Adr2) - return true; - adr = GetParentAdr(adr); - } - return false; -} - -// --------------------------------------------------------------------------- -// Name1 >= Name2 -bool __fastcall IsInheritsByClassName(const String& Name1, const String& Name2) { - DWORD adr = GetClassAdr(Name1); - while (adr) { - if (SameText(GetClsName(adr), Name2)) - return true; - adr = GetParentAdr(adr); - } - return false; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsInheritsByProcName(const String& Name1, const String& Name2) { - return (IsInheritsByClassName(ExtractClassName(Name1), ExtractClassName(Name2)) && SameText(ExtractProcName(Name1), ExtractProcName(Name2))); -} - -// --------------------------------------------------------------------------- -String __fastcall TransformString(char* str, int len) { - bool s = true; // true - print string, false - print #XX - BYTE c, *p = (BYTE*)str; - String res = ""; - - for (int k = 0; k < len; k++) { - c = *p; - p++; - if (!(c & 0x80) && c <= 13) { - if (s) { - if (k) - res += "'+"; - } - else - res += "+"; - res += "#" + String((int)c); - s = false; - } - else { - if (s) { - if (!k) - res += "'"; - } - else - res += "+"; - s = true; - } - if (c == 0x22) - res += "\""; - else if (c == 0x27) - res += "'"; - else if (c == 0x5C) - res += "\\"; - else if (c > 13) - res += (char)c; - } - if (s) - res += "'"; - return res; -} - -// --------------------------------------------------------------------------- -String __fastcall TransformUString(WORD codePage, wchar_t* data, int len) { - if (!IsValidCodePage(codePage)) - codePage = CP_ACP; - int nChars = WideCharToMultiByte(codePage, 0, data, -1, 0, 0, 0, 0); - if (!nChars) - return ""; - char* tmpBuf = new char[nChars + 1]; - WideCharToMultiByte(codePage, 0, data, -1, tmpBuf, nChars, 0, 0); - tmpBuf[nChars] = 0; - String res = QuotedStr(tmpBuf); - delete[]tmpBuf; - return res; -} - -// --------------------------------------------------------------------------- -// Get stop address for analyzing virtual tables -DWORD __fastcall GetStopAt(DWORD VmtAdr) { - int m; - DWORD pos, pointer, stopAt = CodeBase + TotalSize; - - if (DelphiVersion != 2) { - pos = Adr2Pos(VmtAdr) + VmtIntfTable; - for (m = VmtIntfTable; m != VmtInstanceSize; m += 4, pos += 4) { - pointer = *((DWORD*)(Code + pos)); - if (pointer >= VmtAdr && pointer < stopAt) - stopAt = pointer; - } - } - else { - pos = Adr2Pos(VmtAdr) + VmtInitTable; - for (m = VmtInitTable; m != VmtInstanceSize; m += 4, pos += 4) { - if (Adr2Pos(VmtAdr) < 0) - return 0; - pointer = *((DWORD*)(Code + pos)); - if (pointer >= VmtAdr && pointer < stopAt) - stopAt = pointer; - } - } - return stopAt; -} - -// --------------------------------------------------------------------------- -String __fastcall GetTypeName(DWORD adr) { - if (!IsValidImageAdr(adr)) - return "?"; - if (IsFlagSet(cfImport, Adr2Pos(adr))) { - PInfoRec recN = GetInfoRec(adr); - return recN->GetName(); - } - - int pos = Adr2Pos(adr); - if (IsFlagSet(cfRTTI, pos)) - pos += 4; - // TypeKind - BYTE kind = *(Code + pos); - pos++; - BYTE len = *(Code + pos); - pos++; - String Result = String((char*)(Code + pos), len); - if (Result[1] == '.') { - PUnitRec recU = FMain_11011981->GetUnit(adr); - if (recU) { - String prefix; - switch (kind) { - case ikEnumeration: - prefix = "_Enum_"; - break; - case ikArray: - prefix = "_Arr_"; - break; - case ikDynArray: - prefix = "_DynArr_"; - break; - default: - prefix = FMain_11011981->GetUnitName(recU); - break; - } - Result = prefix + String((int)recU->iniOrder) + "_" + Result.SubString(2, len); - } - } - return Result; -} - -// --------------------------------------------------------------------------- -String __fastcall GetDynaInfo(DWORD adr, WORD id, DWORD* dynAdr) { - int m; - DWORD classAdr = adr; - PInfoRec recN; - PMethodRec recM; - - *dynAdr = 0; - - if (!IsValidCodeAdr(adr)) - return ""; - - while (classAdr) { - recN = GetInfoRec(classAdr); - if (recN && recN->vmtInfo && recN->vmtInfo->methods) { - for (m = 0; m < recN->vmtInfo->methods->Count; m++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[m]; - if (recM->kind == 'D' && recM->id == id) { - *dynAdr = recM->address; - if (recM->name != "") - return recM->name; - return ""; // GetDefaultProcName(recM->address); - } - } - } - classAdr = GetParentAdr(classAdr); - } - return ""; -} - -// --------------------------------------------------------------------------- -String __fastcall GetDynArrayTypeName(DWORD adr) { - Byte len; - int pos; - - pos = Adr2Pos(adr); - pos += 4; - pos++; // Kind - len = Code[pos]; - pos++; - pos += len; // Name - pos += 4; // elSize - return GetTypeName(*((DWORD*)(Code + pos))); -} - -// --------------------------------------------------------------------------- -int __fastcall GetTypeSize(String AName) { - int idx = -1; - WORD* uses; - MTypeInfo tInfo; - - uses = KnowledgeBase.GetTypeUses(AnsiString(AName).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(AName).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) { - if (tInfo.Size) - return tInfo.Size; - } - } - return 4; -} -// --------------------------------------------------------------------------- -#define TypeKindsNum 22 -String TypeKinds[TypeKindsNum] = { - "Unknown", "Integer", "Char", "Enumeration", "Float", "ShortString", "Set", "Class", "Method", "WChar", "AnsiString", "WideString", "Variant", "Array", "Record", "Interface", "Int64", "DynArray", - "UString", "ClassRef", "Pointer", "Procedure"}; - -// --------------------------------------------------------------------------- -String __fastcall TypeKind2Name(BYTE kind) { - if (kind < TypeKindsNum) - return TypeKinds[kind]; - else - return ""; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall GetOwnTypeAdr(String AName) { - if (AName == "") - return 0; - PTypeRec recT = GetOwnTypeByName(AName); - if (recT) - return recT->adr; - return 0; -} - -// --------------------------------------------------------------------------- -PTypeRec __fastcall GetOwnTypeByName(String AName) { - if (AName == "") - return 0; - for (int m = 0; m < OwnTypeList->Count; m++) { - PTypeRec recT = (PTypeRec)OwnTypeList->Items[m]; - if (SameText(recT->name, AName)) - return recT; - } - return 0; -} - -// --------------------------------------------------------------------------- -String __fastcall GetTypeDeref(String ATypeName) { - int idx = -1; - WORD* uses; - MTypeInfo tInfo; - - if (ATypeName[1] == '^') - return ATypeName.SubString(2, ATypeName.Length()); - - // Scan knowledgeBase - uses = KnowledgeBase.GetTypeUses(AnsiString(ATypeName).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(ATypeName).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) { - if (tInfo.Decl != "" && tInfo.Decl[1] == '^') - return tInfo.Decl.SubString(2, tInfo.Decl.Length()); - } - } - return ""; -} - -// --------------------------------------------------------------------------- -int __fastcall GetRTTIRecordSize(DWORD adr) { - BYTE len; - int pos, kind, _ap; - - _ap = Adr2Pos(adr); - pos = _ap; - pos += 4; - kind = Code[pos]; - pos++; - len = Code[pos]; - pos += len + 1; - - if (kind == ikRecord) - return*((int*)(Code + pos)); - else - return 0; -} - -// --------------------------------------------------------------------------- -BYTE __fastcall GetTypeKind(String AName, int* size) { - BYTE res; - int pos, idx = -1, kind; - WORD* uses; - MTypeInfo tInfo; - String name, typeName, str; - - *size = 4; - if (AName != "") { - if (AName.Pos("array")) { - if (AName.Pos("array of")) - return ikDynArray; - return ikArray; - } - - pos = AName.LastDelimiter("."); - if (pos > 1 && AName[pos + 1] != ':') - name = AName.SubString(pos + 1, AName.Length()); - else - name = AName; - - if (SameText(name, "Boolean") || SameText(name, "ByteBool") || SameText(name, "WordBool") || SameText(name, "LongBool")) { - return ikEnumeration; - } - if (SameText(name, "ShortInt") || SameText(name, "Byte") || SameText(name, "SmallInt") || SameText(name, "Word") || SameText(name, "Dword") || SameText(name, "Integer") || SameText(name, - "LongInt") || SameText(name, "LongWord") || SameText(name, "Cardinal")) { - return ikInteger; - } - if (SameText(name, "Char")) { - return ikChar; - } - if (SameText(name, "Text") || SameText(name, "File")) { - return ikRecord; - } - - if (SameText(name, "Int64")) { - *size = 8; - return ikInt64; - } - if (SameText(name, "Single")) { - return ikFloat; - } - if (SameText(name, "Real48") || SameText(name, "Real") || SameText(name, "Double") || SameText(name, "TDate") || SameText(name, "TTime") || SameText(name, "TDateTime") || SameText(name, - "Comp") || SameText(name, "Currency")) { - *size = 8; - return ikFloat; - } - if (SameText(name, "Extended")) { - *size = 12; - return ikFloat; - } - if (SameText(name, "ShortString")) - return ikString; - if (SameText(name, "String") || SameText(name, "AnsiString")) - return ikLString; - if (SameText(name, "WideString")) - return ikWString; - if (SameText(name, "UnicodeString") || SameText(name, "UString")) - return ikUString; - if (SameText(name, "PChar") || SameText(name, "PAnsiChar")) - return ikCString; - if (SameText(name, "PWideChar")) - return ikWCString; - if (SameText(name, "Variant")) - return ikVariant; - if (SameText(name, "Pointer")) - return ikPointer; - - // File - AnsiString recFileName = FMain_11011981->WrkDir + "\\types.idr"; - FILE* recFile = fopen(recFileName.c_str(), "rt"); - if (recFile) { - while (1) { - if (!fgets(StringBuf, 1024, recFile)) - break; - str = String(StringBuf); - if (str.Pos(AName + "=") == 1) { - if (str.Pos("=record")) { - fclose(recFile); - return ikRecord; - } - } - } - fclose(recFile); - } - // RTTI - PTypeRec recT = GetOwnTypeByName(name); - if (recT) { - *size = GetRTTIRecordSize(recT->adr); - if (!*size) - * size = 4; - return recT->kind; - } - // Scan KB - uses = KnowledgeBase.GetTypeUses(AnsiString(name).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(name).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) { - if (tInfo.Kind == 'Z') // drAlias??? - return ikUnknown; - if (tInfo.Decl != "" && tInfo.Decl[1] == '^') { - return ikUnknown; - // res = GetTypeKind(tInfo.Decl.SubString(2, tInfo.Decl.Length()), size); - // if (res) return res; - // return 0; - } - *size = tInfo.Size; - switch (tInfo.Kind) { - case drRangeDef: - return ikEnumeration; - case drPtrDef: - return ikMethod; - case drProcTypeDef: - return ikMethod; - case drSetDef: - return ikSet; - case drRecDef: - return ikRecord; - case drInterfaceDef: - return ikInterface; - } - if (tInfo.Decl != "") { - res = GetTypeKind(tInfo.Decl, size); - if (res) - return res; - } - } - } - // May be Interface name - if (AName[1] == 'I') { - AName[1] = 'T'; - if (GetTypeKind(AName, size) == ikVMT) - return ikInterface; - } - // Manual - } - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall GetPackedTypeSize(String AName) { - int _size; - if (SameText(AName, "Boolean") || SameText(AName, "ShortInt") || SameText(AName, "Byte") || SameText(AName, "Char")) { - return 1; - } - if (SameText(AName, "SmallInt") || SameText(AName, "Word")) { - return 2; - } - if (SameText(AName, "Dword") || SameText(AName, "Integer") || SameText(AName, "LongInt") || SameText(AName, "LongWord") || SameText(AName, "Cardinal") || SameText(AName, "Single")) { - return 4; - } - if (SameText(AName, "Real48")) { - return 6; - } - if (SameText(AName, "Real") || SameText(AName, "Double") || SameText(AName, "Comp") || SameText(AName, "Currency") || SameText(AName, "Int64")) { - return 8; - } - if (SameText(AName, "Extended")) { - return 10; - } - if (GetTypeKind(AName, &_size) == ikRecord) { - return GetRecordSize(AName); - } - return 4; -} - -// --------------------------------------------------------------------------- -// return string representation of immediate value with comment -String __fastcall GetImmString(int Val) { - String _res; - String _res0 = String((int)Val); - if (Val > -16 && Val < 16) - return _res0; - _res = String("$") + Val2Str0(Val); - if (!IsValidImageAdr(Val)) - _res += "{" + _res0 + "}"; - return _res; -} - -// --------------------------------------------------------------------------- -String __fastcall GetImmString(String TypeName, int Val) { - int _size; - String _str, _default = GetImmString(Val); - BYTE _kind = GetTypeKind(TypeName, &_size); - if (!Val && (_kind == ikString || _kind == ikLString || _kind == ikWString || _kind == ikUString)) - return "''"; - if (!Val && (_kind == ikClass || _kind == ikVMT)) - return "Nil"; - if (_kind == ikEnumeration) { - _str = GetEnumerationString(TypeName, Val); - if (_str != "") - return _str; - return _default; - } - if (_kind == ikChar) - return Format("'%s'", ARRAYOFCONST(((Char)Val))); - return _default; -} - -// --------------------------------------------------------------------------- -PInfoRec __fastcall GetInfoRec(DWORD adr) { - int pos = Adr2Pos(adr); - if (pos >= 0) - return Infos[pos]; - - int _idx = BSSInfos->IndexOf(Val2Str8(adr)); - if (_idx != -1) - return (PInfoRec)BSSInfos->Objects[_idx]; - - return 0; -} - -// --------------------------------------------------------------------------- -String __fastcall GetEnumerationString(String TypeName, Variant Val) { - BYTE len; - int n, pos, _val, idx; - DWORD adr, typeAdr, minValue, maxValue, minValueB, maxValueB; - char *p, *b, *e; - WORD *uses; - MTypeInfo tInfo; - String clsName; - - if (Val.Type() == varString) - return VarToStr(Val); - - _val = Val; - - if (SameText(TypeName, "Boolean") || SameText(TypeName, "ByteBool") || SameText(TypeName, "WordBool") || SameText(TypeName, "LongBool")) { - if (_val) - return "True"; - else - return "False"; - } - - adr = GetOwnTypeAdr(TypeName); - // RTTI exists - if (IsValidImageAdr(adr)) { - pos = Adr2Pos(adr); - pos += 4; - // typeKind - pos++; - len = Code[pos]; - pos++; - clsName = String((char*)(Code + pos), len); - pos += len; - // ordType - pos++; - minValue = *((DWORD*)(Code + pos)); - pos += 4; - maxValue = *((DWORD*)(Code + pos)); - pos += 4; - // BaseTypeAdr - typeAdr = *((DWORD*)(Code + pos)); - pos += 4; - - // If BaseTypeAdr != SelfAdr then fields extracted from BaseType - if (typeAdr != adr) { - pos = Adr2Pos(typeAdr); - pos += 4; // SelfPointer - pos++; // typeKind - len = Code[pos]; - pos++; - pos += len; // BaseClassName - pos++; // ordType - minValueB = *((DWORD*)(Code + pos)); - pos += 4; - maxValueB = *((DWORD*)(Code + pos)); - pos += 4; - pos += 4; // BaseClassPtr - } - else { - minValueB = minValue; - maxValueB = maxValue; - } - - for (n = minValueB; n <= maxValueB; n++) { - len = Code[pos]; - pos++; - if (n >= minValue && n <= maxValue && n == _val) { - return String((char*)(Code + pos), len); - } - pos += len; - } - } - // Try get from KB - else { - uses = KnowledgeBase.GetTypeUses(AnsiString(TypeName).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(TypeName).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS | INFO_DUMP, &tInfo)) { - if (tInfo.Kind == drRangeDef) - return VarToStr(Val); - // if (SameText(TypeName, tInfo.TypeName) && tInfo.Decl != "") - if (tInfo.Decl != "") { - p = AnsiString(tInfo.Decl).c_str(); - e = p; - for (n = 0; n <= _val; n++) { - b = e + 1; - e = strchr(b, ','); - if (!e) - return ""; - } - return tInfo.Decl.SubString(b - p + 1, e - b); - } - } - } - } - return ""; -} - -// --------------------------------------------------------------------------- -String __fastcall GetSetString(String TypeName, BYTE* ValAdr) { - int n, m, idx, size; - BYTE b, *pVal; - char *pDecl, *p; - WORD *uses; - MTypeInfo tInfo; - String name, result = ""; - - // Get from KB - uses = KnowledgeBase.GetTypeUses(AnsiString(TypeName).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(TypeName).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) { - if (tInfo.Decl.Pos("set of ")) { - size = tInfo.Size; - name = TrimTypeName(tInfo.Decl.SubString(8, TypeName.Length())); - uses = KnowledgeBase.GetTypeUses(AnsiString(name).c_str()); - idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(name).c_str()); - if (uses) - delete[]uses; - - if (idx != -1) { - idx = KnowledgeBase.TypeOffsets[idx].NamId; - if (KnowledgeBase.GetTypeInfo(idx, INFO_DUMP, &tInfo)) { - pVal = ValAdr; - pDecl = AnsiString(tInfo.Decl).c_str(); - p = strtok(pDecl, ",()"); - for (n = 0; n < size; n++) { - b = *pVal; - for (m = 0; m < 8; m++) { - if (b & ((DWORD)1 << m)) { - if (result != "") - result += ","; - if (p) - result += String(p); - else - result += "$" + Val2Str2(n * 8 + m); - } - if (p) - p = strtok(0, ",)"); - } - pVal++; - } - } - } - } - } - } - if (result != "") - result = "[" + result + "]"; - return result; -} - -// --------------------------------------------------------------------------- -void __fastcall OutputDecompilerHeader(FILE* f) { - int n = sprintf(StringBuf, "IDR home page: http://kpnc.org/idr32/en"); - int m = sprintf(StringBuf, "Decompiled by IDR v.%s", IDRVersion.c_str()); - if (n < m) - n = m; - - memset(StringBuf, '*', n); - StringBuf[n] = 0; - fprintf(f, "//%s\n", StringBuf); - - fprintf(f, "//IDR home page: http://kpnc.org/idr32/en\n", StringBuf); - - sprintf(StringBuf, "Decompiled by IDR v.%s", IDRVersion.c_str()); - fprintf(f, "//%s\n", StringBuf); - - memset(StringBuf, '*', n); - StringBuf[n] = 0; - fprintf(f, "//%s\n", StringBuf); -} - -// --------------------------------------------------------------------------- -void __fastcall AddFieldXref(PFIELDINFO fInfo, DWORD ProcAdr, int ProcOfs, char type) { - PXrefRec recX; - - if (!fInfo->xrefs) - fInfo->xrefs = new TList; - - if (!fInfo->xrefs->Count) { - recX = new XrefRec; - recX->type = type; - recX->adr = ProcAdr; - recX->offset = ProcOfs; - fInfo->xrefs->Add((void*)recX); - return; - } - - int F = 0; - recX = (PXrefRec)fInfo->xrefs->Items[F]; - if (ProcAdr + ProcOfs < recX->adr + recX->offset) { - recX = new XrefRec; - recX->type = type; - recX->adr = ProcAdr; - recX->offset = ProcOfs; - fInfo->xrefs->Insert(F, (void*)recX); - return; - } - int L = fInfo->xrefs->Count - 1; - recX = (PXrefRec)fInfo->xrefs->Items[L]; - if (ProcAdr + ProcOfs > recX->adr + recX->offset) { - recX = new XrefRec; - recX->type = type; - recX->adr = ProcAdr; - recX->offset = ProcOfs; - fInfo->xrefs->Add((void*)recX); - return; - } - while (F < L) { - int M = (F + L) / 2; - recX = (PXrefRec)fInfo->xrefs->Items[M]; - if (ProcAdr + ProcOfs <= recX->adr + recX->offset) - L = M; - else - F = M + 1; - } - recX = (PXrefRec)fInfo->xrefs->Items[L]; - if (ProcAdr + ProcOfs != recX->adr + recX->offset) { - recX = new XrefRec; - recX->type = type; - recX->adr = ProcAdr; - recX->offset = ProcOfs; - fInfo->xrefs->Insert(L, (void*)recX); - } -} - -// --------------------------------------------------------------------------- -int __fastcall ArgsCmpFunction(void *item1, void *item2) { - PARGINFO rec1 = (PARGINFO)item1; - PARGINFO rec2 = (PARGINFO)item2; - - if (rec1->Ndx > rec2->Ndx) - return 1; - if (rec1->Ndx < rec2->Ndx) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall ExportsCmpFunction(void *item1, void *item2) { - PExportNameRec rec1 = (PExportNameRec)item1; - PExportNameRec rec2 = (PExportNameRec)item2; - if (rec1->address > rec2->address) - return 1; - if (rec1->address < rec2->address) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall ImportsCmpFunction(void *item1, void *item2) { - PImportNameRec rec1 = (PImportNameRec)item1; - PImportNameRec rec2 = (PImportNameRec)item2; - if (rec1->address > rec2->address) - return 1; - if (rec1->address < rec2->address) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall MethodsCmpFunction(void *item1, void *item2) { - PMethodRec rec1 = (PMethodRec)item1; - PMethodRec rec2 = (PMethodRec)item2; - - if (rec1->kind > rec2->kind) - return 1; - if (rec1->kind < rec2->kind) - return -1; - if (rec1->id > rec2->id) - return 1; - if (rec1->id < rec2->id) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall AddPicode(int Pos, BYTE Op, String Name, int Ofs) { - if (Name == "") - return; - - PInfoRec recN = GetInfoRec(Pos2Adr(Pos)); - // if (recN && recN->picode) return; - - if (!recN) - recN = new InfoRec(Pos, ikUnknown); - if (!recN->picode) - recN->picode = new PICODE; - recN->picode->Op = Op; - recN->picode->Name = Name; - if (Op == OP_CALL) - recN->picode->Ofs.Address = Ofs; - else - recN->picode->Ofs.Offset = Ofs; -} - -// --------------------------------------------------------------------------- -int __fastcall SortUnitsByAdr(void *item1, void* item2) { - PUnitRec recU1 = (PUnitRec)item1; - PUnitRec recU2 = (PUnitRec)item2; - if (recU1->toAdr > recU2->toAdr) - return 1; - if (recU1->toAdr < recU2->toAdr) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall SortUnitsByOrd(void *item1, void* item2) { - PUnitRec recU1 = (PUnitRec)item1; - PUnitRec recU2 = (PUnitRec)item2; - if (recU1->iniOrder > recU2->iniOrder) - return 1; - if (recU1->iniOrder < recU2->iniOrder) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall SortUnitsByNam(void *item1, void* item2) { - PUnitRec recU1 = (PUnitRec)item1; - PUnitRec recU2 = (PUnitRec)item2; - String name1 = ""; - for (int n = 0; n < recU1->names->Count; n++) { - if (n) - name1 += "+"; - name1 += recU1->names->Strings[n]; - } - String name2 = ""; - for (int n = 0; n < recU2->names->Count; n++) { - if (n) - name2 += "+"; - name2 += recU2->names->Strings[n]; - } - int result = CompareText(name1, name2); - if (result) - return result; - if (recU1->toAdr > recU2->toAdr) - return 1; - if (recU1->toAdr < recU2->toAdr) - return -1; - return 0; -} - -// --------------------------------------------------------------------------- -String __fastcall GetArrayElementType(String arrType) { - DWORD adr = GetOwnTypeAdr(arrType); - if (IsValidImageAdr(adr) && IsFlagSet(cfRTTI, Adr2Pos(adr))) - return GetDynArrayTypeName(adr); - - int pos = arrType.Pos(" of "); - if (!pos) - return ""; - return Trim(arrType.SubString(pos + 4, arrType.Length())); -} - -// --------------------------------------------------------------------------- -int __fastcall GetArrayElementTypeSize(String arrType) { - String _elType; - - _elType = GetArrayElementType(arrType); - if (_elType == "") - return 0; - - if (SameText(_elType, "procedure")) - return 8; - return GetTypeSize(_elType); -} - -// --------------------------------------------------------------------------- -// array [N1..M1,N2..M2,...,NK..MK] of Type -// A:array [N..M] of Size -// A[K]: [A + (K - N1)*Size] = [A - N1*Size + K*Size] -// A:array [N1..M1,N2..M2] of Size <=> array [N1..M1] of array [N2..M2] of Size -// A[K,L]: [A + (K - N1)*Dim2*Size + (L - N2)*Size] -// A:array [N1..M1,N2..M2,N3..M3] of Size <=> array [N1..M1] of array [N2..M2,N3..M3] of Size -// A[K,L,R]: [A + (K - N1)*Dim2*Dim3*Size + (L - N2)*Dim3*Size + (R - M3)*Size] -// A[I1,I2,...,IK]: [A + (I1 - N1L)*S/(N1H - N1L) + (I2 - N2L)*S/(N1H - N1L)*(N2H - N2L) + ... + (IK - NKL)*S/S] (*Size) -bool __fastcall GetArrayIndexes(String arrType, int ADim, int* LowIdx, int* HighIdx) { - char c, *p, *b; - int _dim, _val, _pos; - String _item, _item1, _item2; - - *LowIdx = 1; - *HighIdx = 1; // by default - strcpy(StringBuf, AnsiString(arrType).c_str()); - p = strchr(StringBuf, '['); - if (!p) - return false; - p++; - b = p; - _dim = 0; - while (1) { - c = *p; - if (c == ',' || c == ']') { - _dim++; - if (_dim == ADim) { - *p = 0; - _item = String(b).Trim(); - _pos = _item.Pos(".."); - if (!_pos) - * LowIdx = 0; // Type - else { - _item1 = _item.SubString(1, _pos - 1); - if (TryStrToInt(_item1, _val)) - * LowIdx = _val; - else - *LowIdx = 0; // Type - _item2 = _item.SubString(_pos + 2, _item.Length()); - if (TryStrToInt(_item2, _val)) - * HighIdx = _val; - else - *HighIdx = 0; // Type - } - return true; - } - if (c == ']') - break; - } - p++; - } - return false; -} - -// --------------------------------------------------------------------------- -int __fastcall GetArraySize(String arrType) { - char c, *p, *b; - int _dim, _val, _pos, _result = 1, _lIdx, _hIdx, _elTypeSize; - String _item, _item1, _item2; - - _elTypeSize = GetArrayElementTypeSize(arrType); - if (_elTypeSize == 0) - return 0; - - strcpy(StringBuf, AnsiString(arrType).c_str()); - p = strchr(StringBuf, '['); - if (!p) - return 0; - p++; - b = p; - _dim = 0; - while (1) { - c = *p; - if (c == ',' || c == ']') { - _dim++; - *p = 0; - _item = String(b).Trim(); - _pos = _item.Pos(".."); - if (!_pos) - _lIdx = 0; // Type - else { - _item1 = _item.SubString(1, _pos - 1); - if (TryStrToInt(_item1, _val)) - _lIdx = _val; - else - _lIdx = 0; // Type - _item2 = _item.SubString(_pos + 2, _item.Length()); - if (TryStrToInt(_item2, _val)) - _hIdx = _val; - else - _hIdx = 0; // Type - } - if (_hIdx < _lIdx) - return 0; - _result *= (_hIdx - _lIdx + 1); - if (c == ']') { - _result *= _elTypeSize; - break; - } - b = p + 1; - } - p++; - } - return _result; -} - -// --------------------------------------------------------------------------- -/* - String __fastcall GetArrayElement(String arrType, int offset) - { - String _result = ""; - int _arrSize, _elTypeSize; - - _arrSize = GetArraySize(arrType); - if (_arrSize == 0) return ""; - - _elTypeSize = GetArrayElementTypeSize(arrType); - - strcpy(StringBuf, arrType.c_str()); - p = strchr(StringBuf, '['); - if (!p) return ""; - p++; b = p; _dim = 0; - while (1) - { - c = *p; - if (c == ',' || c == ']') - { - _dim++; - *p = 0; - _item = String(b).Trim(); - _pos = _item.Pos(".."); - if (!_pos) - _lIdx = 0;//Type - else - { - _item1 = _item.SubString(1, _pos - 1); - if (TryStrToInt(_item1, _val)) - _lIdx = _val; - else - _lIdx = 0;//Type - _item2 = _item.SubString(_pos + 2, _item.Length()); - if (TryStrToInt(_item2, _val)) - _hIdx = _val; - else - _hIdx = 0;//Type - } - if (_hIdx - _lIdx + 1 <= 0) return ""; - if (offset > _arrSize / (_hIdx - _lIdx + 1)) - { - - } - if (c == ']') - { - _result *= _elTypeSize; - break; - } - b = p + 1; - } - p++; - } - return _result; - } - */ -// --------------------------------------------------------------------------- -void __fastcall Copy2Clipboard(TStrings* items, int leftMargin, bool asmCode) { - int n, bufLen = 0; - String line; - - Screen->Cursor = crHourGlass; - - for (n = 0; n < items->Count; n++) { - line = items->Strings[n]; - bufLen += line.Length() + 2; - } - // Ïîñëåäíèé ñèìâîë äîëæåí áûòü 0 - bufLen++; - - if (bufLen) { - char* buf = new char[bufLen]; - if (buf) { - Clipboard()->Open(); - // Çàïèõèâàåì âñå äàííûå â áóôåð - char *p = buf; - for (n = 0; n < items->Count; n++) { - line = items->Strings[n]; - p += sprintf(p, "%s", line.c_str() + leftMargin); - if (asmCode && n) - p--; - *p = '\r'; - p++; - *p = '\n'; - p++; - } - - *p = 0; - Clipboard()->SetTextBuf(String(buf).c_str()); - Clipboard()->Close(); - - delete[]buf; - } - } - - Screen->Cursor = crDefault; -} - -// --------------------------------------------------------------------------- -String __fastcall GetModuleVersion(const String& module) { - DWORD dwDummy; - DWORD dwFVISize = GetFileVersionInfoSize(AnsiString(module).c_str(), &dwDummy); - if (!dwFVISize) - return ""; - - String strVersion = ""; // empty means not found, etc - some error - - LPBYTE lpVersionInfo = new BYTE[dwFVISize]; - if (GetFileVersionInfo(AnsiString(module).c_str(), 0, dwFVISize, lpVersionInfo)) { - UINT uLen; - VS_FIXEDFILEINFO *lpFfi; - if (VerQueryValue(lpVersionInfo, _T("\\"), (LPVOID*)&lpFfi, &uLen)) { - DWORD dwFileVersionMS = lpFfi->dwFileVersionMS; - DWORD dwFileVersionLS = lpFfi->dwFileVersionLS; - DWORD dwLeftMost = HIWORD(dwFileVersionMS); - DWORD dwSecondLeft = LOWORD(dwFileVersionMS); - DWORD dwSecondRight = HIWORD(dwFileVersionLS); - DWORD dwRightMost = LOWORD(dwFileVersionLS); - - strVersion.sprintf(L"%d.%d.%d.%d", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); - } - } - delete[]lpVersionInfo; - return strVersion; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsBplByExport(const char* bpl) { - PIMAGE_NT_HEADERS pHeader = 0; - PIMAGE_EXPORT_DIRECTORY pExport = 0; - DWORD *pFuncNames = 0; - WORD *pFuncOrdinals = 0; - DWORD *pFuncAddr = 0; - DWORD pName = 0; - DWORD imageBase = 0; - char* szDll = 0; - bool result = 0; - bool haveInitializeFunc = false; - bool haveFinalizeFunc = false; - bool haveGetPackageInfoTableFunc = false; - - HMODULE hLib = LoadLibraryEx(bpl, 0, LOAD_LIBRARY_AS_DATAFILE); - imageBase = (DWORD)(DWORD_PTR)hLib; - - if (hLib) { - pHeader = ImageNtHeader(hLib); - - if (pHeader && pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress && pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) { - pExport = (PIMAGE_EXPORT_DIRECTORY)(DWORD_PTR)(pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + imageBase); - - szDll = (char*)(imageBase + pExport->Name); - - pFuncOrdinals = (WORD*)(imageBase + pExport->AddressOfNameOrdinals); - pFuncNames = (DWORD*)(imageBase + pExport->AddressOfNames); - pFuncAddr = (DWORD*)(imageBase + pExport->AddressOfFunctions); - - for (int i = 0; i < pExport->NumberOfFunctions; i++) { - int index = -1; - for (int j = 0; j < pExport->NumberOfNames; j++) { - if (pFuncOrdinals[j] == i) { - index = j; - break; - } - } - if (index != -1) { - pName = pFuncNames[index]; - String curFunc = String((char*)imageBase + pName); - // Every BPL has a function called @GetPackageInfoTable, Initialize and Finalize. - // lets catch it! - if (!haveInitializeFunc) - haveInitializeFunc = (curFunc == "Initialize"); - if (!haveFinalizeFunc) - haveFinalizeFunc = (curFunc == "Finalize"); - if (!haveGetPackageInfoTableFunc) - haveGetPackageInfoTableFunc = (curFunc == "@GetPackageInfoTable"); - } - if (haveInitializeFunc && haveFinalizeFunc && haveGetPackageInfoTableFunc) - break; - } - - result = haveInitializeFunc && haveFinalizeFunc; - } - FreeLibrary(hLib); - } - return result; -} - -// --------------------------------------------------------------------------- -// toAdr:dec reg -int __fastcall IsInitStackViaLoop(DWORD fromAdr, DWORD toAdr) { - int stackSize = 0; - DWORD dd, curAdr; - int instrLen; - DISINFO _disInfo; - - curAdr = fromAdr; - while (curAdr <= toAdr) { - instrLen = Disasm.Disassemble(curAdr, &_disInfo, 0); - // if (!instrLen) return 0; - if (!instrLen) { - curAdr++; - continue; - } - dd = *((DWORD*)_disInfo.Mnem); - // push ... - if (dd == 'hsup') { - stackSize += 4; - curAdr += instrLen; - continue; - } - // add esp, ... - if (dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == 20 && _disInfo.OpType[1] == otIMM) { - if ((int)_disInfo.Immediate < 0) - stackSize -= (int)_disInfo.Immediate; - curAdr += instrLen; - continue; - } - // sub esp, ... - if (dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == 20 && _disInfo.OpType[1] == otIMM) { - if ((int)_disInfo.Immediate > 0) - stackSize += (int)_disInfo.Immediate; - curAdr += instrLen; - continue; - } - // dec - if (dd == 'ced') { - curAdr += instrLen; - if (curAdr == toAdr) - return stackSize; - } - break; - } - return 0; -} -// --------------------------------------------------------------------------- -int IdxToIdx32Tab[24] = {16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 20, 21, 22, 23, 16, 17, 18, 19, 20, 21, 22, 23}; - -int __fastcall GetReg32Idx(int Idx) { - return IdxToIdx32Tab[Idx]; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsSameRegister(int Idx1, int Idx2) { - return (GetReg32Idx(Idx1) == GetReg32Idx(Idx2)); -} - -// --------------------------------------------------------------------------- -// Is register al, ah, ax, eax, dl, dh, dx, edx, cl, ch, cx, ecx -bool __fastcall IsADC(int Idx) { - int _idx = GetReg32Idx(Idx); - return (_idx == 16 || _idx == 17 || _idx == 18); -} - -// --------------------------------------------------------------------------- -bool __fastcall IsAnalyzedAdr(DWORD Adr) { - bool analyze = false; - for (int n = 0; n < SegmentList->Count; n++) { - PSegmentInfo segInfo = (PSegmentInfo)SegmentList->Items[n]; - if (segInfo->Start <= Adr && Adr < segInfo->Start + segInfo->Size) { - if (!(segInfo->Flags & 0x80000)) - analyze = true; - break; - } - } - return analyze; -} - -// --------------------------------------------------------------------------- -// Check that fromAdr is BoundErr sequence -int __fastcall IsBoundErr(DWORD fromAdr) { - int _pos, _instrLen; - DWORD _adr; - PInfoRec _recN; - DISINFO _disInfo; - - _pos = Adr2Pos(fromAdr); - _adr = fromAdr; - while (IsFlagSet(cfSkip, _pos)) { - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - _adr += _instrLen; - if (_disInfo.Call && IsValidImageAdr(_disInfo.Immediate)) { - _recN = GetInfoRec(_disInfo.Immediate); - if (_recN->SameName("@BoundErr")) - return _adr - fromAdr; - } - _pos += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -bool __fastcall IsConnected(DWORD fromAdr, DWORD toAdr) { - int n, _pos, _instrLen; - DWORD _adr; - DISINFO _disInfo; - - _pos = Adr2Pos(fromAdr); - _adr = fromAdr; - for (n = 0; n < 32; n++) { - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - if (_disInfo.Conditional && _disInfo.Immediate == toAdr) - return true; - _pos += _instrLen; - _adr += _instrLen; - } - return false; -} - -// --------------------------------------------------------------------------- -// Check that fromAdr points to Exit -bool __fastcall IsExit(DWORD fromAdr) { - BYTE _op; - int _pos, _instrLen; - DWORD _adr; - DISINFO _disInfo; - - if (!IsValidCodeAdr(fromAdr)) - return 0; - _pos = Adr2Pos(fromAdr); - _adr = fromAdr; - - while (1) { - if (!IsFlagSet(cfFinally | cfExcept, _pos)) - break; - _pos += 8; - _adr += 8; - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_PUSH || _op == OP_JMP) { - _adr = _disInfo.Immediate; - _pos = Adr2Pos(_adr); - } - else { - return false; - } - } - while (1) { - _instrLen = Disasm.Disassemble(Code + _pos, (__int64)_adr, &_disInfo, 0); - if (_disInfo.Ret) - return true; - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_POP) { - _pos += _instrLen; - _adr += _instrLen; - continue; - } - if (_op == OP_MOV && _disInfo.OpType[0] == otREG && (IsSameRegister(_disInfo.OpRegIdx[0], 16) || IsSameRegister(_disInfo.OpRegIdx[0], 20))) { - _pos += _instrLen; - _adr += _instrLen; - continue; - } - break; - } - return false; -} - -// --------------------------------------------------------------------------- -DWORD __fastcall IsGeneralCase(DWORD fromAdr, int retAdr) { - int _regIdx = -1, _pos; - DWORD _dd; - DWORD _curAdr = fromAdr, _jmpAdr = 0; - int _curPos = Adr2Pos(fromAdr); - int _len, _num1 = 0; - DISINFO _disInfo; - - if (!IsValidCodeAdr(fromAdr)) - return 0; - - while (1) { - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - // Switch at current address - if (IsFlagSet(cfSwitch, _curPos)) { - Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'aj') { - if (IsValidCodeAdr(_disInfo.Immediate)) - return _disInfo.Immediate; - else - return 0; - } - } - // Switch at next address - if (IsFlagSet(cfSwitch, _curPos + _len)) { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'aj') { - if (IsValidCodeAdr(_disInfo.Immediate)) - return _disInfo.Immediate; - else - return 0; - } - } - // cmp reg, imm - if (_dd == 'pmc' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) { - _regIdx = _disInfo.OpRegIdx[0]; - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bj' || _dd == 'gj' || _dd == 'egj') { - if (IsGeneralCase(_disInfo.Immediate, retAdr)) { - _curAdr += _len; - _curPos += _len; - - _len = Disasm.Disassemble(Code + _curPos, (__int64)(_curAdr), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - _curAdr += _len; - _curPos += _len; - // continue; - } - continue; - } - break; - } - } - // sub reg, imm; dec reg - if ((_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'ced' && _disInfo.OpType[0] == otREG)) { - _num1++; - if (_regIdx == -1) - _regIdx = _disInfo.OpRegIdx[0]; - else if (!IsSameRegister(_regIdx, _disInfo.OpRegIdx[0])) - break; - - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bus' && IsSameRegister(_regIdx, _disInfo.OpRegIdx[0])) { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - } - if (_dd == 'bj') { - _curAdr += _len; - _curPos += _len; - _len = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - _curAdr += _len; - _curPos += _len; - } - continue; - } - if (_dd == 'zj' || _dd == 'ej') { - _pos = GetNearestUpInstruction(Adr2Pos(_disInfo.Immediate)); - Disasm.Disassemble(Code + _pos, (__int64)Pos2Adr(_pos), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'pmj') - _jmpAdr = _disInfo.Immediate; - if (_disInfo.Ret) - _jmpAdr = Pos2Adr(GetLastLocPos(retAdr)); - _curAdr += _len; - _curPos += _len; - continue; - } - if (_dd == 'znj' || _dd == 'enj') { - if (!_jmpAdr) { - // if only one dec or sub then it is simple if...else construction - if (_num1 == 1) - return 0; - return _disInfo.Immediate; - } - if (_disInfo.Immediate == _jmpAdr) - return _jmpAdr; - } - break; - } - // add reg, imm; inc reg - if ((_dd == 'dda' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM) || (_dd == 'cni' && _disInfo.OpType[0] == otREG)) { - _num1++; - if (_regIdx == -1) - _regIdx = _disInfo.OpRegIdx[0]; - else if (!IsSameRegister(_regIdx, _disInfo.OpRegIdx[0])) - break; - - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bus') { - _len += Disasm.Disassemble(Code + _curPos + _len, (__int64)(_curAdr + _len), &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bj') { - _curAdr += _len; - _curPos += _len; - continue; - } - } - if (_dd == 'zj' || _dd == 'ej') { - _curAdr += _len; - _curPos += _len; - continue; - } - break; - } - if (_dd == 'pmj') { - if (IsValidCodeAdr(_disInfo.Immediate)) - return _disInfo.Immediate; - else - return 0; - } - break; - } - return 0; -} - -// --------------------------------------------------------------------------- -// check -// xor reg, reg -// mov reg,... -bool __fastcall IsXorMayBeSkipped(DWORD fromAdr) { - DWORD _curAdr = fromAdr, _dd; - int _instrlen, _regIdx; - int _curPos = Adr2Pos(fromAdr); - DISINFO _disInfo; - - _instrlen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'rox' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) { - _regIdx = _disInfo.OpRegIdx[0]; - _curPos += _instrlen; - _curAdr += _instrlen; - Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'vom' && _disInfo.OpType[0] == otREG && IsSameRegister(_disInfo.OpRegIdx[0], _regIdx)) - return true; - } - return false; -} - -// --------------------------------------------------------------------------- -String __fastcall UnmangleName(String Name) { - int pos; - // skip first '@' - String Result = Name.SubString(2, Name.Length()); - AnsiString LeftPart = Result; - AnsiString RightPart = ""; - - int breakPos = Result.Pos("$"); - if (breakPos) { - if (breakPos == 1) // - LeftPart = Result.SubString(1, breakPos - 1); - RightPart = Result.SubString(breakPos + 1, Result.Length()); - } - if (*LeftPart.AnsiLastChar() == '@') - LeftPart.SetLength(LeftPart.Length() - 1); - while (1) { - pos = LeftPart.Pos("@@"); - if (!pos) - break; - LeftPart[pos + 1] = '_'; - } - int num = 0; - while (1) { - pos = LeftPart.Pos("@"); - if (!pos) - break; - LeftPart[pos] = '.'; - num++; - } - while (1) { - pos = LeftPart.Pos("._"); - if (!pos) - break; - LeftPart[pos + 1] = '@'; - } -} - -// --------------------------------------------------------------------------- -// Check construction (after cdq) -// xor eax, edx -// sub eax, edx -// return bytes to skip, if Abs, else return 0 -int __fastcall IsAbs(DWORD fromAdr) { - int _curPos = Adr2Pos(fromAdr), _instrLen; - DWORD _dd, _curAdr = fromAdr; - DISINFO _disInfo; - - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'rox' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[0] == 16 && _disInfo.OpRegIdx[1] == 18) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[0] == 16 && _disInfo.OpRegIdx[1] == 18) { - return (_curAdr + _instrLen) - fromAdr; - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction -// jxx @1 -// call @IntOver -// @1: -// return bytes to skip, if @IntOver, else return 0 -int _fastcall IsIntOver(DWORD fromAdr) { - int _instrLen, _curPos = Adr2Pos(fromAdr); - DWORD _curAdr = fromAdr; - PInfoRec _recN; - DISINFO _disInfo; - - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - if (_disInfo.Branch && _disInfo.Conditional) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - if (_disInfo.Call) { - if (IsValidCodeAdr(_disInfo.Immediate)) { - _recN = GetInfoRec(_disInfo.Immediate); - if (_recN && _recN->SameName("@IntOver")) - return (_curAdr + _instrLen) - fromAdr; - } - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction (test reg, reg) -// test reg, reg -// jz @1 -// mov reg, [reg-4] -// or------------------------------------------------------------------------- -// test reg, reg -// jz @1 -// sub reg, 4 -// mov reg, [reg] -int __fastcall IsInlineLengthTest(DWORD fromAdr) { - int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx = -1; - DWORD _dd, _adr = 0, _curAdr = fromAdr; - DISINFO _disInfo; - - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'tset' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) { - _regIdx = _disInfo.OpRegIdx[0]; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - _adr = _disInfo.Immediate; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - // mov reg, [reg-4] - if (_dd == 'vom' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == _regIdx && _disInfo.IndxReg == -1 && _disInfo.Offset == -4) { - if (_adr == _curAdr + _instrLen) - return (_curAdr + _instrLen) - fromAdr; - } - // sub reg, 4 - if (_dd == 'bus' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM && _disInfo.Immediate == 4) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - // mov reg, [reg] - if (_dd == 'vom' && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == _regIdx && _disInfo.IndxReg == -1 && _disInfo.Offset == 0) { - if (_adr == _curAdr + _instrLen) - return (_curAdr + _instrLen) - fromAdr; - } - } - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// cmp [lvar], 0 -// jz @1 -// mov reg, [lvar] -// sub reg, 4 -// mov reg, [reg] -// mov [lvar], reg -int __fastcall IsInlineLengthCmp(DWORD fromAdr) { - BYTE _op; - int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx = -1; - int _baseReg, _offset; - DWORD _dd, _adr = 0, _curAdr = fromAdr; - DISINFO _disInfo; - - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_CMP && _disInfo.OpType[0] == otMEM && _disInfo.OpType[1] == otIMM && _disInfo.Immediate == 0) { - _baseReg = _disInfo.BaseReg; - _offset = _disInfo.Offset; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'zj' || _dd == 'ej') { - _adr = _disInfo.Immediate; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // mov reg, [lvar] - if (_op == OP_MOV && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == _baseReg && _disInfo.Offset == _offset) { - _regIdx = _disInfo.OpRegIdx[0]; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // sub reg, 4 - if (_op == OP_SUB && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM && _disInfo.Immediate == 4) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // mov reg, [reg] - if (_op == OP_MOV && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == _regIdx && _disInfo.IndxReg == -1 && _disInfo.Offset == 0) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - // mov [lvar], reg - if (_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.OpType[1] == otREG && _disInfo.BaseReg == _baseReg && _disInfo.Offset == _offset) { - if (_adr == _curAdr + _instrLen) - return (_curAdr + _instrLen) - fromAdr; - } - } - } - } - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// test reg, reg -// jns @1 -// add reg, (2^k - 1) -// sar reg, k -// @1 -int __fastcall IsInlineDiv(DWORD fromAdr, int* div) { - BYTE _op; - int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx = -1; - DWORD _dd, _adr, _curAdr = fromAdr, _imm; - DISINFO _disInfo; - - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_TEST && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1]) { - _regIdx = _disInfo.OpRegIdx[0]; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'snj') { - _adr = _disInfo.Immediate; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_ADD && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == _regIdx && _disInfo.OpType[1] == otIMM) { - _imm = _disInfo.Immediate + 1; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_SAR && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == _regIdx && _disInfo.OpType[1] == otIMM) { - if (((DWORD)1 << _disInfo.Immediate) == _imm) { - *div = _imm; - return (_curAdr + _instrLen) - fromAdr; - } - } - } - } - } - return 0; -} - -// --------------------------------------------------------------------------- -// and reg, imm -// jns @1 -// dec reg -// or reg, imm -// inc reg -// @1 -int __fastcall IsInlineMod(DWORD fromAdr, int* mod) { - BYTE _op; - int _curPos = Adr2Pos(fromAdr), _instrLen, _regIdx = -1; - DWORD _dd, _adr = 0, _curAdr = fromAdr, _imm; - DISINFO _disInfo; - - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_AND && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM && (_disInfo.Immediate & 0x80000000) != 0) { - _regIdx = _disInfo.OpRegIdx[0]; - _imm = _disInfo.Immediate & 0x7FFFFFFF; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _dd = *((DWORD*)_disInfo.Mnem); - if (_dd == 'snj') { - _adr = _disInfo.Immediate; - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_DEC && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == _regIdx) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_OR && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM && _disInfo.OpRegIdx[0] == _regIdx && _disInfo.Immediate + _imm == 0xFFFFFFFF) { - _curPos += _instrLen; - _curAdr += _instrLen; - _instrLen = Disasm.Disassemble(Code + _curPos, (__int64)_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_INC && _disInfo.OpType[0] == otREG && _disInfo.OpRegIdx[0] == _regIdx) { - if (_adr == _curAdr + _instrLen) { - *mod = _imm + 1; - return (_curAdr + _instrLen) - fromAdr; - } - } - } - } - } - } - return 0; -} - -// --------------------------------------------------------------------------- -int __fastcall GetLastLocPos(int fromAdr) { - int _pos = Adr2Pos(fromAdr); - while (1) { - if (IsFlagSet(cfLoc, _pos)) - return _pos; - _pos--; - } -} - -// --------------------------------------------------------------------------- -bool __fastcall IsDefaultName(String AName) { - for (int Idx = 0; Idx < 8; Idx++) { - if (SameText(AName, String(Reg32Tab[Idx]))) - return true; - } - if (SameText(AName.SubString(1, 5), "lvar_")) - return true; - if (SameText(AName.SubString(1, 5), "gvar_")) - return true; - return false; -} - -// --------------------------------------------------------------------------- -int __fastcall FloatNameToFloatType(String AName) { - if (SameText(AName, "Single")) - return FT_SINGLE; - if (SameText(AName, "Double")) - return FT_DOUBLE; - if (SameText(AName, "Extended")) - return FT_EXTENDED; - if (SameText(AName, "Real")) - return FT_REAL; - if (SameText(AName, "Comp")) - return FT_COMP; - if (SameText(AName, "Currency")) - return FT_CURRENCY; - return -1; -} - -// --------------------------------------------------------------------------- -String __fastcall InputDialogExec(String caption, String labelText, String text) { - String _result = ""; - - FInputDlg_11011981->Caption = caption; - FInputDlg_11011981->edtName->EditLabel->Caption = labelText; - FInputDlg_11011981->edtName->Text = text; - while (_result == "") { - if (FInputDlg_11011981->ShowModal() == mrCancel) - break; - _result = FInputDlg_11011981->edtName->Text.Trim(); - } - return _result; -} - -// --------------------------------------------------------------------------- -String __fastcall ManualInput(DWORD procAdr, DWORD curAdr, String caption, String labelText) { - String _result = ""; - - FMain_11011981->ShowCode(procAdr, curAdr, FMain_11011981->lbCXrefs->ItemIndex, -1); - FInputDlg_11011981->Caption = caption; - FInputDlg_11011981->edtName->EditLabel->Caption = labelText; - FInputDlg_11011981->edtName->Text = ""; - while (_result == "") { - if (FInputDlg_11011981->ShowModal() == mrCancel) - break; - _result = FInputDlg_11011981->edtName->Text.Trim(); - } - return _result; -} - -// --------------------------------------------------------------------------- -bool __fastcall MatchCode(BYTE* code, MProcInfo* pInfo) { - if (!code || !pInfo) - return false; - - DWORD _dumpSz = pInfo->DumpSz; - // ret - if (_dumpSz < 2) - return false; - - BYTE *_dump = pInfo->Dump; - BYTE *_relocs = _dump + _dumpSz; - // jmp XXXXXXXX - if (_dumpSz == 5 && _dump[0] == 0xE9 && _relocs[1] == 0xFF) - return false; - // call XXXXXXXX ret - if (_dumpSz == 6 && _dump[0] == 0xE8 && _relocs[1] == 0xFF && _dump[5] == 0xC3) - return false; - - for (int n = 0; n < _dumpSz;) { - // Relos skip - if (_relocs[n] == 0xFF) { - n += 4; - continue; - } - if (code[n] != _dump[n]) - return false; - - n++; - } - - return true; -} -// --------------------------------------------------------------------------- -TColor SavedPenColor; -TColor SavedBrushColor; -TColor SavedFontColor; -TBrushStyle SavedBrushStyle; - -// --------------------------------------------------------------------------- -void __fastcall SaveCanvas(TCanvas* ACanvas) { - SavedPenColor = ACanvas->Pen->Color; - SavedBrushColor = ACanvas->Brush->Color; - SavedFontColor = ACanvas->Font->Color; - SavedBrushStyle = ACanvas->Brush->Style; -} - -// --------------------------------------------------------------------------- -void __fastcall RestoreCanvas(TCanvas* ACanvas) { - ACanvas->Pen->Color = SavedPenColor; - ACanvas->Brush->Color = SavedBrushColor; - ACanvas->Font->Color = SavedFontColor; - ACanvas->Brush->Style = SavedBrushStyle; -} - -// --------------------------------------------------------------------------- -void __fastcall DrawOneItem(String AItem, TCanvas* ACanvas, TRect &ARect, TColor AColor, int flags) { - SaveCanvas(ACanvas); - ARect.Left = ARect.Right; - ARect.Right += ACanvas->TextWidth(AItem); - TRect R1 = Rect(ARect.Left - 1, ARect.Top, ARect.Right, ARect.Bottom - 1); - if (SameText(AItem, SelectedAsmItem)) { - ACanvas->Brush->Color = TColor(0x80DDFF); - ACanvas->Brush->Style = bsSolid; - ACanvas->FillRect(R1); - ACanvas->Brush->Style = bsClear; - ACanvas->Pen->Color = TColor(0x226DA8); ; - ACanvas->Rectangle(R1); - } - ACanvas->Font->Color = AColor; - ACanvas->TextOut(ARect.Left, ARect.Top, AItem); - RestoreCanvas(ACanvas); -} - -// --------------------------------------------------------------------------- -// Check try construction -// xor reg, reg -// push ebp -// push XXXXXXXX -// push fs:[reg] -// mov fs:[reg], esp -int __fastcall IsTryBegin(DWORD fromAdr, DWORD *endAdr) { - BYTE _op; - int _instrLen, n; - DWORD _curAdr, _endAdr; - DISINFO _disInfo; - - _curAdr = fromAdr; - for (n = 1; n <= 5; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) { - if (!(_op == OP_XOR && _disInfo.OpType[0] == _disInfo.OpType[1] && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1])) - break; - } - else if (n == 2) { - if (!(_op == OP_PUSH && _disInfo.OpRegIdx[0] == 21)) - break; - } - else if (n == 3) { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otIMM)) - break; - _endAdr = _disInfo.Immediate; - } - else if (n == 4) { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) - break; - } - else if (n == 5) { - if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) - break; - *endAdr = _endAdr; - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check try construction (Delphi3:Atlantis.exe at 0x50D676) -// push ebp -// push XXXXXXXX -// push fs:[0] -// mov fs:[0], esp -int __fastcall IsTryBegin0(DWORD fromAdr, DWORD *endAdr) { - BYTE _op; - int _instrLen, n; - DWORD _curAdr, _endAdr; - DISINFO _disInfo; - - _curAdr = fromAdr; - for (n = 1; n <= 4; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) { - if (!(_op == OP_PUSH && _disInfo.OpRegIdx[0] == 21)) - break; - } - else if (n == 2) { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otIMM)) - break; - _endAdr = _disInfo.Immediate; - } - else if (n == 3) { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg == -1 && _disInfo.Offset == 0)) - break; - } - else if (n == 4) { - if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg == -1 && _disInfo.Offset == 0)) - break; - *endAdr = _endAdr; - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check finally construction -// xor reg,reg -// pop reg -// pop reg -// pop reg -// mov fs:[reg],reg -// push XXXXXXXX -int __fastcall IsTryEndPush(DWORD fromAdr, DWORD* endAdr) { - BYTE _op; - int _instrLen, n; - DWORD _curAdr; - DISINFO _disInfo; - - _curAdr = fromAdr; - for (n = 1; n <= 6; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) { - if (!(_op == OP_XOR && _disInfo.OpType[0] == _disInfo.OpType[1] && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1])) - break; - } - else if (n >= 2 && n <= 4) { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (n == 5) { - if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) - break; - } - else if (n == 6) { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otIMM)) - break; - *endAdr = _disInfo.Immediate; - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check finally construction -// xor reg,reg -// pop reg -// pop reg -// pop reg -// mov fs:[reg],reg -// jmp XXXXXXXX -int __fastcall IsTryEndJump(DWORD fromAdr, DWORD* endAdr) { - BYTE _op; - int _instrLen, n; - DWORD _curAdr; - DISINFO _disInfo; - - _curAdr = fromAdr; - for (n = 1; n <= 6; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) { - if (!(_op == OP_XOR && _disInfo.OpType[0] == _disInfo.OpType[1] && _disInfo.OpRegIdx[0] == _disInfo.OpRegIdx[1])) - break; - } - else if (n >= 2 && n <= 4) { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (n == 5) { - if (!(_op == OP_MOV && _disInfo.OpType[0] == otMEM && _disInfo.SegPrefix == 4 && _disInfo.BaseReg != -1)) - break; - } - else if (n == 6) { - if (!(_op == OP_JMP && _disInfo.OpType[0] == otIMM)) - break; - *endAdr = _disInfo.Immediate; - return _curAdr - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction equality ((Int64)val = XXX) -// cmp XXX,XXX -> set cfSkip (_skipAdr1 = address of this instruction) -// jne @1 -> set cfSkip (_skipAdr2 = address of this instruction) -// cmp XXX,XXX -// jne @1 -// ... -// @1: -int __fastcall ProcessInt64Equality(DWORD fromAdr, DWORD* maxAdr) { - BYTE _op, _b; - int _instrLen, n, _curPos; - DWORD _curAdr, _adr1, _maxAdr; - DWORD _skipAdr1, _skipAdr2; - DISINFO _disInfo; - - _curAdr = fromAdr; - _curPos = Adr2Pos(_curAdr); - _maxAdr = 0; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - - _b = *(Code + _curPos); - if (_b == 0xF) - _b = *(Code + _curPos + 1); - _b = (_b & 0xF) + 'A'; - - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - _skipAdr1 = _curAdr; - } - else if (n == 2) // jne @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) - break; - _skipAdr2 = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - if (_adr1 > _maxAdr) - _maxAdr = _adr1; - } - else if (n == 3) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - } - else if (n == 4) // jne @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F' && _disInfo.Immediate == _adr1)) - break; - *maxAdr = _maxAdr; - SetFlag(cfSkip, Adr2Pos(_skipAdr1)); - SetFlag(cfSkip, Adr2Pos(_skipAdr2)); - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - _curPos += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction not equality ((Int64)val <> XXX) -// cmp XXX,XXX -> set cfSkip (_skipAdr1 = address of this instruction) -// jne @1 -> set cfSkip (_skipAdr2 = address of this instruction) -// cmp XXX,XXX -// je @2 -// @1: -int __fastcall ProcessInt64NotEquality(DWORD fromAdr, DWORD* maxAdr) { - BYTE _op, _b; - int _instrLen, n, _curPos; - DWORD _curAdr, _adr1, _adr2, _maxAdr; - DWORD _skipAdr1, _skipAdr2; - DISINFO _disInfo; - - _curAdr = fromAdr; - _curPos = Adr2Pos(_curAdr); - _maxAdr = 0; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - - _b = *(Code + _curPos); - if (_b == 0xF) - _b = *(Code + _curPos + 1); - _b = (_b & 0xF) + 'A'; - - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - _skipAdr1 = _curAdr; - } - else if (n == 2) // jne @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) - break; - _skipAdr2 = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - if (_adr1 > _maxAdr) - _maxAdr = _adr1; - } - else if (n == 3) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - } - else if (n == 4) // je @2 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'E' && _curAdr + _instrLen == _adr1)) - break; - _adr2 = _disInfo.Immediate; // @2 - if (_adr2 > _maxAdr) - _maxAdr = _adr2; - *maxAdr = _maxAdr; - SetFlag(cfSkip, Adr2Pos(_skipAdr1)); - SetFlag(cfSkip, Adr2Pos(_skipAdr2)); - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - _curPos += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction comparison ((Int64)val >(<) XXX) -// cmp XXX,XXX -> set cfSkip (_skipAdr1 = address of this instruction) -// jxx @1 -> set cfSkip (_skipAdr2 = address of this instruction) -// cmp XXX,XXX -// jxx @@ -> set cfSkip (_skipAdr3 = address of this instruction) -// jmp @@ set cfSkip (_skipAdr4 = address of this instruction) -// @1:jxx @@ -int __fastcall ProcessInt64Comparison(DWORD fromAdr, DWORD* maxAdr) { - BYTE _op; - int _instrLen, n; - DWORD _curAdr, _adr, _adr1, _maxAdr; - DWORD _skipAdr1, _skipAdr2, _skipAdr3, _skipAdr4; - DISINFO _disInfo; - - _curAdr = fromAdr; - _maxAdr = 0; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - _skipAdr1 = _curAdr; - } - else if (n == 2) // jxx @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _skipAdr2 = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - if (_adr1 > _maxAdr) - _maxAdr = _adr1; - } - else if (n == 3) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - } - else if (n == 4) // jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _skipAdr3 = _curAdr; - _adr = _disInfo.Immediate; // @@ - if (_adr > _maxAdr) - _maxAdr = _adr; - } - else if (n == 5) // jmp @@ - { - if (!(_disInfo.Branch && !_disInfo.Conditional)) - break; - _skipAdr4 = _curAdr; - _adr = _disInfo.Immediate; // @@ - if (_adr > _maxAdr) - _maxAdr = _adr; - } - else if (n == 6) - ////@1:jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional && _curAdr == _adr1)) - break; - _adr = _disInfo.Immediate; // @@ - if (_adr > _maxAdr) - _maxAdr = _adr; - *maxAdr = _maxAdr; - SetFlag(cfSkip, Adr2Pos(_skipAdr1)); - SetFlag(cfSkip, Adr2Pos(_skipAdr2)); - SetFlag(cfSkip, Adr2Pos(_skipAdr3)); - SetFlag(cfSkip, Adr2Pos(_skipAdr4)); - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction comparison ((Int64)val >(<) XXX) -// push reg -// push reg -// ... -// cmp XXX,[esp+4] (m-th row) set cfSkip (_skipAdr1) -// jxx @1 ->set cfSkip (_skipAdr2) -// cmp XXX,[esp] -// @1:pop reg -// pop reg -// jxx @2 -int __fastcall ProcessInt64ComparisonViaStack1(DWORD fromAdr, DWORD* maxAdr) { - BYTE _op; - int _instrLen, n, m, _skip, _pos; - DWORD _curAdr, _adr1, _adr2, _adr3, _maxAdr, _pushAdr; - DWORD _skipAdr1, _skipAdr2; - DISINFO _disInfo; - - _curAdr = fromAdr; - m = -1; - _maxAdr = 0; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - } - else if (n == 2) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - _pushAdr = _curAdr; - } - else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4) // cmp XXX,[esp+4] - { - // Find nearest up instruction "push reg" - _pos = Adr2Pos(_curAdr); - while (1) { - _pos--; - if (_pos == fromAdr) - break; - if (IsFlagSet(cfInstruction, _pos)) { - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_PUSH) - break; - } - } - if (Pos2Adr(_pos) != _pushAdr) - return 0; - m = n; - _skipAdr1 = _curAdr; - } - else if (m != -1 && n == m + 1) // jxx @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _skipAdr2 = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - if (_adr1 > _maxAdr) - _maxAdr = _adr1; - } - else if (m != -1 && n == m + 2) // cmp XXX,[esp] - { - if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) - break; - } - else if (m != -1 && n == m + 3) // @1:pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) - break; - } - else if (m != -1 && n == m + 4) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (m != -1 && n == m + 5) // jxx @2 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - *maxAdr = _maxAdr; - SetFlag(cfSkip, Adr2Pos(_skipAdr1)); - SetFlag(cfSkip, Adr2Pos(_skipAdr2)); - return _curAdr + _instrLen - fromAdr; - } - if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction comparison ((Int64)val >(<) XXX) -// push reg -// push reg -// ... -// cmp XXX,[esp+4] (m-th row) set cfSkip (_skipAdr1) -// jxx @1 ->set cfSkip (_skipAdr2) -// cmp XXX,[esp] -// pop reg ->set cfSkip (_skipAdr3) -// pop reg ->set cfSkip (_skipAdr4) -// jxx @@ ->set cfSkip (_skipAdr5) -// jmp @@ ->set cfSkip (_skipAdr6) -// @1: -// pop reg -// pop reg -// jxx @2 -int __fastcall ProcessInt64ComparisonViaStack2(DWORD fromAdr, DWORD* maxAdr) { - BYTE _op; - int _instrLen, n, m, _skip, _pos; - DWORD _curAdr, _adr, _adr1, _adr2, _maxAdr, _pushAdr; - DWORD _skipAdr1, _skipAdr2, _skipAdr3, _skipAdr4, _skipAdr5, _skipAdr6; - DISINFO _disInfo; - - _curAdr = fromAdr; - m = -1; - _maxAdr = 0; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - } - else if (n == 2) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - _pushAdr = _curAdr; - } - else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4) // cmp XXX,[esp+4] - { - // Find nearest up instruction "push reg" - _pos = Adr2Pos(_curAdr); - while (1) { - _pos--; - if (_pos == fromAdr) - break; - if (IsFlagSet(cfInstruction, _pos)) { - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_PUSH) - break; - } - } - if (Pos2Adr(_pos) != _pushAdr) - return 0; - m = n; - _skipAdr1 = _curAdr; - } - else if (m != -1 && n == m + 1) // jxx @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _skipAdr2 = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - if (_adr1 > _maxAdr) - _maxAdr = _adr1; - } - else if (m != -1 && n == m + 2) // cmp XXX,[esp] - { - if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) - break; - } - else if (m != -1 && n == m + 3) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - _skipAdr3 = _curAdr; - } - else if (m != -1 && n == m + 4) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - _skipAdr4 = _curAdr; - } - else if (m != -1 && n == m + 5) // jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _skipAdr5 = _curAdr; - _adr = _disInfo.Immediate; // @3 - if (_adr > _maxAdr) - _maxAdr = _adr; - } - else if (m != -1 && n == m + 6) // jmp @@ - { - if (!(_disInfo.Branch && !_disInfo.Conditional)) - break; - _skipAdr6 = _curAdr; - _adr = _disInfo.Immediate; // @2 - if (_adr > _maxAdr) - _maxAdr = _adr; - } - else if (m != -1 && n == m + 7) // @1:pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) - break; - } - else if (m != -1 && n == m + 8) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (m != -1 && n == m + 9) // jxx @2 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _adr2 = _disInfo.Immediate; - if (_adr2 > _maxAdr) - _maxAdr = _adr2; - *maxAdr = _maxAdr; - SetFlag(cfSkip, Adr2Pos(_skipAdr1)); - SetFlag(cfSkip, Adr2Pos(_skipAdr2)); - SetFlag(cfSkip, Adr2Pos(_skipAdr3)); - SetFlag(cfSkip, Adr2Pos(_skipAdr4)); - SetFlag(cfSkip, Adr2Pos(_skipAdr5)); - SetFlag(cfSkip, Adr2Pos(_skipAdr6)); - return _curAdr + _instrLen - fromAdr; - } - if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction equality ((Int64)val = XXX) -// cmp XXX,XXX -// jne @1 (_br1Adr = address of this instruction) -// cmp XXX,XXX ->skip1 up to this instruction -// jne @1 -> skip2 up to this instruction, Result = skip2 -// ... -// @1:... -> delete 1 xRef to this instruction (address = _adr1) -int __fastcall IsInt64Equality(DWORD fromAdr, int* skip1, int* skip2, bool *immVal, __int64* Val) { - bool _imm; - BYTE _op, _b; - int _instrLen, n, _curPos, _skip; - DWORD _curAdr, _adr1, _br1Adr; - DISINFO _disInfo; - __int64 _val1, _val2; - // PInfoRec _recN; - - _curAdr = fromAdr; - _curPos = Adr2Pos(_curAdr); - _imm = false; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - - _b = *(Code + _curPos); - if (_b == 0xF) - _b = *(Code + _curPos + 1); - _b = (_b & 0xF) + 'A'; - - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - if (_disInfo.OpType[1] == otIMM) { - _imm = true; - _val1 = _disInfo.Immediate; - } - } - else if (n == 2) // jne @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) - break; - _br1Adr = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - } - else if (n == 3) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - *skip1 = _curAdr - fromAdr; - if (_disInfo.OpType[1] == otIMM) { - _imm = true; - _val2 = _disInfo.Immediate; - } - } - else if (n == 4) // jne @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F' && _disInfo.Immediate == _adr1)) - break; - _skip = _curAdr - fromAdr; - *skip2 = _skip; - *immVal = _imm; - if (_imm) - * Val = (_val1 << 32) | _val2; - return _skip; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - _curPos += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction not equality ((Int64)val <> XXX) -// cmp XXX,XXX -// jne @1 (_br1Adr = address of this instruction) -// cmp XXX,XXX ->skip1 up to this instruction -// je @2 -> skip2 up to this instruction, Result = skip2 -// @1:... -> delete 1 xRef to this instruction (address = _adr1) -int __fastcall IsInt64NotEquality(DWORD fromAdr, int* skip1, int* skip2, bool *immVal, __int64* Val) { - bool _imm; - BYTE _op, _b; - int _instrLen, n, _curPos, _skip; - DWORD _curAdr, _adr1, _adr2, _br1Adr; - DISINFO _disInfo; - __int64 _val1, _val2; - // PInfoRec _recN; - - _curAdr = fromAdr; - _curPos = Adr2Pos(_curAdr); - _imm = false; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - - _b = *(Code + _curPos); - if (_b == 0xF) - _b = *(Code + _curPos + 1); - _b = (_b & 0xF) + 'A'; - - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - if (_disInfo.OpType[1] == otIMM) { - _imm = true; - _val1 = _disInfo.Immediate; - } - } - else if (n == 2) // jne @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'F')) - break; - _br1Adr = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - } - else if (n == 3) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - *skip1 = _curAdr - fromAdr; - if (_disInfo.OpType[1] == otIMM) { - _imm = true; - _val2 = _disInfo.Immediate; - } - } - else if (n == 4) // je @2 - { - if (!(_disInfo.Branch && _disInfo.Conditional && _b == 'E' && _curAdr + _instrLen == _adr1)) - break; - _skip = _curAdr - fromAdr; - *skip2 = _skip; - *immVal = _imm; - if (_imm) - * Val = (_val1 << 32) | _val2; - return _skip; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - _curPos += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction comparison ((Int64)val >(<) XXX) -// cmp XXX,XXX -// jxx @1 (_br1Adr = address of this instruction) -// cmp XXX,XXX ->skip1 up to this instruction -// jxx @@ (_br3Adr = address of this instruction) -// jmp @@ (_br2Adr = address of this instruction) -// @1:jxx @@ (skip2 up to this instruction, Result = skip2) -int __fastcall IsInt64Comparison(DWORD fromAdr, int* skip1, int* skip2, bool* immVal, __int64* Val) { - bool _imm; - BYTE _op; - int _instrLen, n, m, _skip; - __int64 _val1, _val2; - DWORD _curAdr, _adr1, _br1Adr, _br2Adr, _br3Adr; - DISINFO _disInfo; - // PInfoRec _recN; - - _curAdr = fromAdr; - _imm = false; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - if (_disInfo.OpType[1] == otIMM) { - _imm = true; - _val1 = _disInfo.Immediate; - } - } - else if (n == 2) // jxx @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _br1Adr = _curAdr; - _adr1 = _disInfo.Immediate; // @1 - } - else if (n == 3) // cmp XXX,XXX - { - if (!(_op == OP_CMP)) - break; - *skip1 = _curAdr - fromAdr; - if (_disInfo.OpType[1] == otIMM) { - _imm = true; - _val2 = _disInfo.Immediate; - } - } - else if (n == 4) // jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _br3Adr = _curAdr; - } - else if (n == 5) // jmp @@ - { - if (!(_disInfo.Branch && !_disInfo.Conditional)) - break; - _br2Adr = _curAdr; - } - else if (n == 6) - ////@1:jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional && _curAdr == _adr1)) - break; - _skip = _curAdr - fromAdr; - *skip2 = _skip; - *immVal = _imm; - if (_imm) - * Val = (_val1 << 32) | _val2; - return _skip; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction comparison ((Int64)val >(<) N) -// push reg -// push reg -// ... -// cmp XXX,[esp+4] (m-th row) ->Simulate upto this address -// jxx @1 -// cmp XXX,[esp] ->skip1=this position -// @1:pop reg -// pop reg -// jxx @@ ->Result -int __fastcall IsInt64ComparisonViaStack1(DWORD fromAdr, int* skip1, DWORD* simEnd) { - BYTE _op; - int _instrLen, n, m, _pos; - DWORD _curAdr = fromAdr, _adr1, _pushAdr; - DISINFO _disInfo; - - _curAdr = fromAdr; - *skip1 = 0; - *simEnd = 0; - m = -1; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - } - else if (n == 2) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - _pushAdr = _curAdr; - } - else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4) // cmp XXX,[esp+4] - { - // Find nearest up instruction "push reg" - _pos = Adr2Pos(_curAdr); - while (1) { - _pos--; - if (_pos == fromAdr) - break; - if (IsFlagSet(cfInstruction, _pos)) { - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_PUSH) - break; - } - } - if (Pos2Adr(_pos) != _pushAdr) - return 0; - m = n; - *simEnd = _curAdr; - } - else if (m != -1 && n == m + 1) // jxx @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _adr1 = _disInfo.Immediate; // @1 - } - else if (m != -1 && n == m + 2) // cmp XXX,[esp] - { - if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) - break; - *skip1 = _curAdr - fromAdr; - } - else if (m != -1 && n == m + 3) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) - break; - } - else if (m != -1 && n == m + 4) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (m != -1 && n == m + 5) // jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - return _curAdr - fromAdr; - } - if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction comparison ((Int64)val >(<) XXX) -// push reg -// push reg -// ... -// cmp XXX,[esp+4] (m-th row) ->Simulate upto this address -// jxx @1 -// cmp XXX,[esp] ->skip1=this position -// pop reg -// pop reg -// jxx @@ ->skip2 -// jmp @@ -// @1: -// pop reg -// pop reg -// jxx @@ ->Result -int __fastcall IsInt64ComparisonViaStack2(DWORD fromAdr, int* skip1, int* skip2, DWORD* simEnd) { - BYTE _op; - int _instrLen, n, m, _pos; - DWORD _curAdr = fromAdr, _adr1, _pushAdr; - DISINFO _disInfo; - - _curAdr = fromAdr; - *simEnd = 0; - m = -1; - for (n = 1; n <= 1024; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - } - else if (n == 2) // push reg - { - if (!(_op == OP_PUSH && _disInfo.OpType[0] == otREG)) - break; - _pushAdr = _curAdr; - } - else if (n >= 3 && m == -1 && _op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 4) // cmp XXX,[esp+4] - { - // Find nearest up instruction "push reg" - _pos = Adr2Pos(_curAdr); - while (1) { - _pos--; - if (_pos == fromAdr) - break; - if (IsFlagSet(cfInstruction, _pos)) { - Disasm.Disassemble(Pos2Adr(_pos), &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (_op == OP_PUSH) - break; - } - } - if (Pos2Adr(_pos) != _pushAdr) - return 0; - m = n; - *simEnd = _curAdr; - } - else if (m != -1 && n == m + 1) // jxx @1 - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - _adr1 = _disInfo.Immediate; // @1 - } - else if (m != -1 && n == m + 2) // cmp XXX,[esp] - { - if (!(_op == OP_CMP && _disInfo.OpType[1] == otMEM && _disInfo.BaseReg == 20 && _disInfo.Offset == 0)) - break; - *skip1 = _curAdr - fromAdr; - } - else if (m != -1 && n == m + 3) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (m != -1 && n == m + 4) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (m != -1 && n == m + 5) // jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - *skip2 = _curAdr - fromAdr; - } - else if (m != -1 && n == m + 6) // jmp @@ - { - if (!(_disInfo.Branch && !_disInfo.Conditional)) - break; - } - else if (m != -1 && n == m + 7) // @1:pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG && _curAdr == _adr1)) - break; - } - else if (m != -1 && n == m + 8) // pop reg - { - if (!(_op == OP_POP && _disInfo.OpType[0] == otREG)) - break; - } - else if (m != -1 && n == m + 9) // jxx @@ - { - if (!(_disInfo.Branch && _disInfo.Conditional)) - break; - return _curAdr - fromAdr; - } - if (m == -1 && (_disInfo.Ret || _disInfo.Branch)) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction -// shrd reg1,reg2,N -// shr reg2,N -int __fastcall IsInt64Shr(DWORD fromAdr) { - BYTE _op; - int _instrLen, n, _idx, _val; - DWORD _curAdr = fromAdr; - DISINFO _disInfo; - - for (n = 1; n <= 2; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) { - if (!(_op == OP_SHR && _disInfo.OpNum == 3 && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpType[2] == otIMM)) - break; - _idx = _disInfo.OpRegIdx[1]; - _val = _disInfo.Immediate; - } - else if (n == 2) { - if (!(_op == OP_SHR && _disInfo.OpNum == 2 && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otIMM && _disInfo.OpRegIdx[0] == _idx && _disInfo.Immediate == _val)) - break; - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} - -// --------------------------------------------------------------------------- -// Check construction -// shld reg1,reg2,N -// shl reg2,N -int __fastcall IsInt64Shl(DWORD fromAdr) { - BYTE _op; - int _instrLen, n, _idx, _val; - DWORD _curAdr = fromAdr; - DISINFO _disInfo; - - for (n = 1; n <= 2; n++) { - _instrLen = Disasm.Disassemble(_curAdr, &_disInfo, 0); - _op = Disasm.GetOp(_disInfo.Mnem); - if (n == 1) { - if (!(_op == OP_SHL && _disInfo.OpNum == 3 && _disInfo.OpType[0] == otREG && _disInfo.OpType[1] == otREG && _disInfo.OpType[2] == otIMM)) - break; - _idx = _disInfo.OpRegIdx[1]; - _val = _disInfo.Immediate; - } - else if (n == 2) { - if (!(_op == OP_SHL && _disInfo.OpNum == 2 && _disInfo.OpType[0] == otREG && _disInfo.OpType[2] == otIMM && _disInfo.OpRegIdx[0] == _idx && _disInfo.Immediate == _val)) - break; - return _curAdr + _instrLen - fromAdr; - } - if (_disInfo.Ret) - return 0; - _curAdr += _instrLen; - } - return 0; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/PEHeader.cpp b/Sources/Libs/PEHeader.cpp deleted file mode 100644 index 9ebeb94..0000000 --- a/Sources/Libs/PEHeader.cpp +++ /dev/null @@ -1,488 +0,0 @@ -// --------------------------------------------------------------------------- - -#pragma hdrstop - -#include "PEHeader.h" -#include "Misc.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) - -// --------------------------------------------------------------------------- -DWORD TPEHeader::EvaluateInitTable(BYTE* Data, DWORD Size, DWORD Base) { - int i, num, pos, unitsPos = 0, n; - DWORD initTable, result, iniAdr, finAdr, maxAdr = 0; - - for (i = 0; i < ((Size - 4) & (-4)); i += 4) { - initTable = result = *((DWORD*)(Data + i)); - if (initTable == Base + i + 4) { - num = *((DWORD*)(Data + i - 4)); - if (num <= 0 || num > 10000) - continue; - pos = unitsPos = i + 4; - for (n = 0; n < num; n++, pos += 8) { - iniAdr = *((DWORD*)(Data + pos)); - if (iniAdr) { - if (iniAdr < Base || iniAdr >= Base + Size) - // !IsValidImageAdr(iniAdr)) - { - unitsPos = 0; - break; - } - else if (iniAdr > maxAdr) { - maxAdr = iniAdr; - } - } - finAdr = *((DWORD*)(Data + pos + 4)); - if (finAdr) { - if (finAdr < Base || finAdr >= Base + Size) - // !IsValidImageAdr(finAdr)) - { - unitsPos = 0; - break; - } - else if (finAdr > maxAdr) { - maxAdr = finAdr; - } - } - result += 8; - } - if (unitsPos) - break; - } - } - if (maxAdr > result) - result = (maxAdr + 3) & (-4); - - if (unitsPos) - return initTable - 8; - - // May be D2010 - maxAdr = 0; - for (i = 0; i < ((Size - 20) & (-4)); i += 4) { - initTable = result = *((DWORD*)(Data + i)); - if (initTable == Base + i + 20) { - num = *((DWORD*)(Data + i - 4)); - if (num <= 0 || num > 10000) - continue; - - pos = unitsPos = i + 20; - for (n = 0; n < num; n++, pos += 8) { - iniAdr = *((DWORD*)(Data + pos)); - if (iniAdr) { - if (iniAdr < Base || iniAdr >= Base + Size) - // !IsValidImageAdr(iniAdr)) - { - unitsPos = 0; - break; - } - else if (iniAdr > maxAdr) { - if (*((DWORD*)(Data + Adr2Pos(iniAdr)))) - maxAdr = iniAdr; - } - } - finAdr = *((DWORD*)(Data + pos + 4)); - if (finAdr) { - if (finAdr < Base || finAdr >= Base + Size) - // !IsValidImageAdr(finAdr)) - { - unitsPos = 0; - break; - } - else if (finAdr > maxAdr) { - if (*((DWORD*)(Data + Adr2Pos(finAdr)))) - maxAdr = finAdr; - } - } - result += 8; - } - if (unitsPos) - break; - } - } - if (maxAdr > result) - result = (maxAdr + 3) & (-4); - - if (unitsPos) - return initTable - 24; - - return 0; -} - -// --------------------------------------------------------------------------- -bool TPEHeader::ImportsValid(DWORD ImpRVA, DWORD ImpSize) { - if (ImpRVA || ImpSize) { - DWORD EntryRVA = ImpRVA; - DWORD EndRVA = ImpRVA + ImpSize; - IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; - - while (1) { - memmove(&ImportDescriptor, (this->FPEHeader32.Image + Adr2Pos(EntryRVA +this->FPEHeader32.ImageBase)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); - - if (!ImportDescriptor.OriginalFirstThunk && !ImportDescriptor.TimeDateStamp && !ImportDescriptor.ForwarderChain && !ImportDescriptor.Name && !ImportDescriptor.FirstThunk) - break; - - if (!IsValidImageAdr(ImportDescriptor.Name +this->FPEHeader32.ImageBase)) - return false; - int NameLength = strlen((char*)(this->FPEHeader32.Image + Adr2Pos(ImportDescriptor.Name +this->FPEHeader32.ImageBase))); - if (NameLength < 0 || NameLength > 256) - return false; - if (!IsValidModuleName(NameLength, Adr2Pos(ImportDescriptor.Name +this->FPEHeader32.ImageBase))) - return false; - - EntryRVA += sizeof(IMAGE_IMPORT_DESCRIPTOR); - if (EntryRVA >= EndRVA) - break; - } - } - return true; -} - -// --------------------------------------------------------------------------- -int TPEHeader::LoadImage(FILE* f, bool loadExp, bool loadImp) { - int i, n, m, bytes, pos, SectionsNum, ExpNum, NameLength; - DWORD DataEnd, Items; - String moduleName, modName, sEP; - String impFuncName; - IMAGE_DOS_HEADER DosHeader; - IMAGE_NT_HEADERS NTHeaders; - PIMAGE_SECTION_HEADER SectionHeaders; - char segname[9]; - char msg[1024]; - - fseek(f, 0L, SEEK_SET); - // IDD_ERR_NOT_EXECUTABLE - if (fread(&DosHeader, 1, sizeof(IMAGE_DOS_HEADER), f) != sizeof(IMAGE_DOS_HEADER) || DosHeader.e_magic != IMAGE_DOS_SIGNATURE) { - ShowMessage("File is not executable"); - return 0; - } - - fseek(f, DosHeader.e_lfanew, SEEK_SET); - // IDD_ERR_NOT_PE_EXECUTABLE - if (fread(&NTHeaders, 1, sizeof(IMAGE_NT_HEADERS), f) != sizeof(IMAGE_NT_HEADERS) || NTHeaders.Signature != IMAGE_NT_SIGNATURE) { - ShowMessage("File is not PE-executable"); - return 0; - } - // IDD_ERR_INVALID_PE_EXECUTABLE - if (NTHeaders.FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER) || NTHeaders.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ShowMessage("File is invalid 32-bit PE-executable"); - return 0; - } - // IDD_ERR_INVALID_PE_EXECUTABLE - SectionsNum = NTHeaders.FileHeader.NumberOfSections; - if (!SectionsNum) { - ShowMessage("File is invalid PE-executable"); - return 0; - } - // SizeOfOptionalHeader may be > than sizeof(IMAGE_OPTIONAL_HEADER) - fseek(f, NTHeaders.FileHeader.SizeOfOptionalHeader -sizeof(IMAGE_OPTIONAL_HEADER), SEEK_CUR); - SectionHeaders = new IMAGE_SECTION_HEADER[SectionsNum]; - - if (fread(SectionHeaders, 1, sizeof(IMAGE_SECTION_HEADER) * SectionsNum, f) != sizeof(IMAGE_SECTION_HEADER) * SectionsNum) { - ShowMessage("Invalid section headers"); - delete[]SectionHeaders; - return 0; - } - - this->FPEHeader32.ImageBase = NTHeaders.OptionalHeader.ImageBase; - this->FPEHeader32.ImageSize = NTHeaders.OptionalHeader.SizeOfImage; - this->FPEHeader32.EP = NTHeaders.OptionalHeader.AddressOfEntryPoint; - - this->FPEHeader32.TotalSize = 0; - DWORD rsrcVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - DWORD relocVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - // Fill SegmentList - for (i = 0; i < SectionsNum; i++) { - PSegmentInfo segInfo = new SegmentInfo; - segInfo->Start = SectionHeaders[i].VirtualAddress +this->FPEHeader32.ImageBase; - segInfo->Flags = SectionHeaders[i].Characteristics; - - if (i + 1 < SectionsNum) - segInfo->Size = SectionHeaders[i + 1].VirtualAddress - SectionHeaders[i].VirtualAddress; - else - segInfo->Size = SectionHeaders[i].Misc.VirtualSize; - - if (!SectionHeaders[i].SizeOfRawData) // uninitialized data - { - // segInfo->Size = SectionHeaders[i].Misc.VirtualSize; - segInfo->Flags |= 0x80000; - } - else if (SectionHeaders[i].VirtualAddress == rsrcVA || SectionHeaders[i].VirtualAddress == relocVA) { - // segInfo->Size = SectionHeaders[i].SizeOfRawData; - segInfo->Flags |= 0x80000; - } - else { - // segInfo->Size = SectionHeaders[i].SizeOfRawData; - this->FPEHeader32.TotalSize += segInfo->Size; - } - memset(segname, 0, 9); - memmove(segname, SectionHeaders[i].Name, 8); - segInfo->Name = String(segname); - this->FPEHeader32.SegmentList->Add((void*)segInfo); - } - // DataEnd = TotalSize; - - // Load Image into memory - this->FPEHeader32.Image = new BYTE[this->FPEHeader32.TotalSize]; - memset((void*)this->FPEHeader32.Image, 0, this->FPEHeader32.TotalSize); - int num; - BYTE *p = this->FPEHeader32.Image; - for (i = 0; i < SectionsNum; i++) { - if (SectionHeaders[i].VirtualAddress == rsrcVA || SectionHeaders[i].VirtualAddress == relocVA) - continue; - BYTE *sp = p; - fseek(f, SectionHeaders[i].PointerToRawData, SEEK_SET); - DWORD Items = SectionHeaders[i].SizeOfRawData; - if (Items) { - for (n = 0; Items >= MAX_ITEMS; n++) { - fread(p, 1, MAX_ITEMS, f); - Items -= MAX_ITEMS; - p += MAX_ITEMS; - } - if (Items) { - fread(p, 1, Items, f); - p += Items; - } - num = p -this->FPEHeader32.Image; - if (i + 1 < SectionsNum) - p = sp + (SectionHeaders[i + 1].VirtualAddress - SectionHeaders[i].VirtualAddress); - } - } - - this->FPEHeader32.CodeStart = 0; - this->FPEHeader32.Code = this->FPEHeader32.Image +this->FPEHeader32.CodeStart; - this->FPEHeader32.CodeBase = this->FPEHeader32.ImageBase + SectionHeaders[0].VirtualAddress; - - DWORD evalInitTable = TPEHeader::EvaluateInitTable(this->FPEHeader32.Image, this->FPEHeader32.TotalSize, this->FPEHeader32.CodeBase); - if (!evalInitTable) { - ShowMessage("Cannot find initialization table"); - delete[]SectionHeaders; - delete[]this->FPEHeader32.Image; - this->FPEHeader32.Image = 0; - return 0; - } - - DWORD evalEP = 0; - // Find instruction mov eax,offset InitTable - for (n = 0; n < this->FPEHeader32.TotalSize - 5; n++) { - if (this->FPEHeader32.Image[n] == 0xB8 && *((DWORD*)(this->FPEHeader32.Image + n + 1)) == evalInitTable) { - evalEP = n; - break; - } - } - // Scan up until bytes 0x55 (push ebp) and 0x8B,0xEC (mov ebp,esp) - if (evalEP) { - while (evalEP != 0) { - if (this->FPEHeader32.Image[evalEP] == 0x55 && this->FPEHeader32.Image[evalEP + 1] == 0x8B && this->FPEHeader32.Image[evalEP + 2] == 0xEC) - break; - evalEP--; - } - } - // Check evalEP - if (evalEP +this->FPEHeader32.CodeBase != NTHeaders.OptionalHeader.AddressOfEntryPoint +this->FPEHeader32.ImageBase) { - sprintf( - msg, - "Possible invalid EP (NTHeader:%lX, Evaluated:%lX). Input valid EP?", - NTHeaders.OptionalHeader.AddressOfEntryPoint +this->FPEHeader32.ImageBase, - evalEP +this->FPEHeader32.CodeBase - ); - - if (Application->MessageBox(String(msg).c_str(), L"Confirmation", MB_YESNO) == IDYES) { - sEP = InputDialogExec("New EP", "EP:", Val2Str0(NTHeaders.OptionalHeader.AddressOfEntryPoint +this->FPEHeader32.ImageBase)); - if (sEP != "") { - sscanf(AnsiString(sEP).c_str(), "%lX", &this->FPEHeader32.EP); - if (!IsValidImageAdr(this->FPEHeader32.EP)) { - delete[]SectionHeaders; - delete[]this->FPEHeader32.Image; - this->FPEHeader32.Image = 0; - return 0; - } - } - else { - delete[]SectionHeaders; - delete[]this->FPEHeader32.Image; - this->FPEHeader32.Image = 0; - return 0; - } - } - else { - delete[]SectionHeaders; - delete[]this->FPEHeader32.Image; - this->FPEHeader32.Image = 0; - return 0; - } - } - else { - this->FPEHeader32.EP = NTHeaders.OptionalHeader.AddressOfEntryPoint +this->FPEHeader32.ImageBase; - } - // Find DataStart - // DWORD _codeEnd = DataEnd; - // DataStart = CodeStart; - // for (i = 0; i < SectionsNum; i++) - // { - // if (SectionHeaders[i].VirtualAddress + ImageBase > EP) - // { - // _codeEnd = SectionHeaders[i].VirtualAddress; - // DataStart = SectionHeaders[i].VirtualAddress; - // break; - // } - // } - delete[]SectionHeaders; - - this->FPEHeader32.CodeSize = this->FPEHeader32.TotalSize; // _codeEnd - SectionHeaders[0].VirtualAddress; - // DataSize = DataEnd - DataStart; - // DataBase = ImageBase + DataStart; - - this->FPEHeader32.Flags = new DWORD[this->FPEHeader32.TotalSize]; - memset(this->FPEHeader32.Flags, cfUndef, sizeof(DWORD)* this->FPEHeader32.TotalSize); - this->FPEHeader32.Infos = new PInfoRec[this->FPEHeader32.TotalSize]; - memset(this->FPEHeader32.Infos, 0, sizeof(PInfoRec)* this->FPEHeader32.TotalSize); - this->FPEHeader32.BSSInfos = new TStringList; - this->FPEHeader32.BSSInfos->Sorted = true; - - if (loadExp) { - // Load Exports - DWORD ExpRVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - // DWORD ExpSize = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - - if (ExpRVA) { - IMAGE_EXPORT_DIRECTORY ExportDescriptor; - memmove(&ExportDescriptor, (this->FPEHeader32.Image + Adr2Pos(ExpRVA +this->FPEHeader32.ImageBase)), sizeof(IMAGE_EXPORT_DIRECTORY)); - ExpNum = ExportDescriptor.NumberOfFunctions; - DWORD ExpFuncNamPos = ExportDescriptor.AddressOfNames; - DWORD ExpFuncAdrPos = ExportDescriptor.AddressOfFunctions; - DWORD ExpFuncOrdPos = ExportDescriptor.AddressOfNameOrdinals; - - for (i = 0; i < ExpNum; i++) { - PExportNameRec recE = new ExportNameRec; - - DWORD dp = *((DWORD*)(this->FPEHeader32.Image + Adr2Pos(ExpFuncNamPos +this->FPEHeader32.ImageBase))); - NameLength = strlen((char*)(this->FPEHeader32.Image + Adr2Pos(dp +this->FPEHeader32.ImageBase))); - recE->name = String((char*)(this->FPEHeader32.Image + Adr2Pos(dp +this->FPEHeader32.ImageBase)), NameLength); - - WORD dw = *((WORD*)(this->FPEHeader32.Image + Adr2Pos(ExpFuncOrdPos +this->FPEHeader32.ImageBase))); - recE->address = *((DWORD*)(this->FPEHeader32.Image + Adr2Pos(ExpFuncAdrPos + 4 * dw +this->FPEHeader32.ImageBase)))+this->FPEHeader32.ImageBase; - recE->ord = dw + ExportDescriptor.Base; - this->FPEHeader32.ExpFuncList->Add((void*)recE); - - ExpFuncNamPos += 4; - ExpFuncOrdPos += 2; - } - this->FPEHeader32.ExpFuncList->Sort(ExportsCmpFunction); - } - } - - DWORD ImpRVA = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - DWORD ImpSize = NTHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; - - if (loadImp && (ImpRVA || ImpSize)) { - if (!ImportsValid(ImpRVA, ImpSize)) { - ShowMessage("Imports not valid, will skip!"); - } - else { - // Load Imports - DWORD EntryRVA; // Next import decriptor RVA - DWORD EndRVA; // End of imports - DWORD ThunkRVA; // RVA of next thunk (from FirstThunk) - DWORD LookupRVA; - // RVA of next thunk (from OriginalFirstTunk or FirstThunk) - DWORD ThunkValue; - // Value of next thunk (from OriginalFirstTunk or FirstThunk) - WORD Hint; // Ordinal or hint of imported symbol - - IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; - - // DWORD fnProc = 0; - - // First import descriptor - EntryRVA = ImpRVA; - EndRVA = ImpRVA + ImpSize; - - while (1) { - memmove(&ImportDescriptor, (this->FPEHeader32.Image + Adr2Pos(EntryRVA +this->FPEHeader32.ImageBase)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); - // All descriptor fields are NULL - end of list, break - if (!ImportDescriptor.OriginalFirstThunk && !ImportDescriptor.TimeDateStamp && !ImportDescriptor.ForwarderChain && !ImportDescriptor.Name && !ImportDescriptor.FirstThunk) - break; - - NameLength = strlen((char*)(this->FPEHeader32.Image + Adr2Pos(ImportDescriptor.Name +this->FPEHeader32.ImageBase))); - moduleName = String((char*)(this->FPEHeader32.Image + Adr2Pos(ImportDescriptor.Name +this->FPEHeader32.ImageBase)), NameLength); - - int pos = moduleName.Pos("."); - if (pos) - modName = moduleName.SubString(1, pos - 1); - else - modName = moduleName; - - if (-1 == this->FPEHeader32.ImpModuleList->IndexOf(moduleName)) - this->FPEHeader32.ImpModuleList->Add(moduleName); - - // HINSTANCE hLib = LoadLibraryEx(moduleName.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); - - // Define the source of import names (OriginalFirstThunk or FirstThunk) - if (ImportDescriptor.OriginalFirstThunk) - LookupRVA = ImportDescriptor.OriginalFirstThunk; - else - LookupRVA = ImportDescriptor.FirstThunk; - - // ThunkRVA get from FirstThunk always - ThunkRVA = ImportDescriptor.FirstThunk; - // Get Imported Functions - while (1) { - // Names or ordinals get from LookupTable (this table can be inside OriginalFirstThunk or FirstThunk) - ThunkValue = *((DWORD*)(this->FPEHeader32.Image + Adr2Pos(LookupRVA +this->FPEHeader32.ImageBase))); - if (!ThunkValue) - break; - - // fnProc = 0; - PImportNameRec recI = new ImportNameRec; - - if (ThunkValue & 0x80000000) { - // By ordinal - Hint = (WORD)(ThunkValue & 0xFFFF); - - // if (hLib) fnProc = (DWORD)GetProcAddress(hLib, (char*)Hint); - - // Addresse get from FirstThunk only - // recI->name = modName + "." + String(Hint); - recI->name = String(Hint); - } - else { - // by name - Hint = *((WORD*)(this->FPEHeader32.Image + Adr2Pos(ThunkValue +this->FPEHeader32.ImageBase))); - NameLength = lstrlen((char*)(this->FPEHeader32.Image + Adr2Pos(ThunkValue + 2+this->FPEHeader32.ImageBase))); - impFuncName = String((char*)(this->FPEHeader32.Image + Adr2Pos(ThunkValue + 2+this->FPEHeader32.ImageBase)), NameLength); - - // if (hLib) - // { - // fnProc = (DWORD)GetProcAddress(hLib, impFuncName.c_str()); - // memmove((void*)(Image + ThunkRVA), (void*)&fnProc, sizeof(DWORD)); - // } - - recI->name = impFuncName; - } - recI->module = modName; - recI->address = this->FPEHeader32.ImageBase + ThunkRVA; - this->FPEHeader32.ImpFuncList->Add((void*)recI); - // - SetFlag(cfImport, Adr2Pos(recI->address)); - PInfoRec recN = new InfoRec(Adr2Pos(recI->address), ikData); - recN->SetName(impFuncName); - // - ThunkRVA += 4; - LookupRVA += 4; - } - EntryRVA += sizeof(IMAGE_IMPORT_DESCRIPTOR); - if (EntryRVA >= EndRVA) - break; - - // if (hLib) - // { - // FreeLibrary(hLib); - // hLib = NULL; - // } - } - this->FPEHeader32.ImpFuncList->Sort(ImportsCmpFunction); - } - } - return 1; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/PEHeader.h b/Sources/Libs/PEHeader.h deleted file mode 100644 index 5c7cf0c..0000000 --- a/Sources/Libs/PEHeader.h +++ /dev/null @@ -1,52 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef PEHeaderH -#define PEHeaderH - -#include -#include -#include "Singleton.h" -#include "Infos.h" -// --------------------------------------------------------------------------- - -struct TPEHeader32 { - DWORD EP; - DWORD ImageBase; - DWORD ImageSize; - DWORD TotalSize; // Size of sections CODE + DATA - DWORD CodeBase; - DWORD CodeSize; - DWORD CodeStart; - PInfoRec *Infos; // = 0; // Array of pointers to store items data - TStringList *BSSInfos; // = 0; // Data from BSS - DWORD *Flags; // = 0; // flags for used data - TList *SegmentList; // Information about Image Segments - TList *ExpFuncList; // Exported functions list (temporary) - TList *ImpFuncList; // Imported functions list (temporary) - TStringList *ImpModuleList; // Imported modules list (temporary) - - /* - * Buffers - */ - BYTE *Code; - BYTE *Image; -}; - -// --------------------------------------------------------------------------- -class TPEHeader { -private: - TPEHeader32 FPEHeader32; - - bool ImportsValid(DWORD ImpRVA, DWORD ImpSize); - -public: - static DWORD EvaluateInitTable(BYTE* Data, DWORD Size, DWORD Base); - int LoadImage(FILE* f, bool loadExp, bool loadImp); - - __property TPEHeader32 PEHeader32 = {read = FPEHeader32}; -}; - -// --------------------------------------------------------------------------- -typedef TSingleton STPEHeader; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/ProcessManager.cpp b/Sources/Libs/ProcessManager.cpp deleted file mode 100644 index 4e16fd5..0000000 --- a/Sources/Libs/ProcessManager.cpp +++ /dev/null @@ -1,319 +0,0 @@ -// --------------------------------------------------------------------------- - -#pragma hdrstop - -#include "ProcessManager.h" - -#include -#include -// --------------------------------------------------------------------------- -#pragma package(smart_init) - -// --------------------------------------------------------------------------- -bool TProcessManager::GenerateProcessList() { - - // Clear current process list - this->FList.clear(); - - // Get the list of process identifiers. - DWORD aProcesses[1024], cbNeeded, cProcesses; - unsigned int i; - - if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) { - return false; - } - - // Calculate how many process identifiers were returned. - cProcesses = cbNeeded / sizeof(DWORD); - - // Print the name and process identifier for each process. - for (i = 0; i < cProcesses; i++) { - if (aProcesses[i] != 0) { - - // Get a handle to the process. - HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]); - - // Get the process name. - if (NULL != hProcess) { - HMODULE hModule; - DWORD cbNeeded; - - // Get modules list (for this case, only the first module) - if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded)) { - HANDLE hSnapshot; - MODULEENTRY32 me = {}; - me.dwSize = sizeof(MODULEENTRY32); - // Get name and base - hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, aProcesses[i]); - if (hSnapshot != INVALID_HANDLE_VALUE) { - // Get module info - Module32First(hSnapshot, &me); - // Release the handle to the process. - CloseHandle(hSnapshot); - - MODULEINFO modinfo = {}; - if (GetModuleInformation(hProcess, hModule, &modinfo, sizeof(modinfo))) { - // Save process info - TProcess Process = {}; - Process.Pid = aProcesses[i]; - Process.ImageSize = modinfo.SizeOfImage; - Process.EntryPoint = (DWORD) modinfo.EntryPoint; - Process.BaseAddress = (DWORD) me.modBaseAddr; - Process.Name = ExtractFileName(String(me.szExePath)); - this->FList.push_back(Process); - } - } - } - } - - // Release the handle to the process. - CloseHandle(hProcess); - } - } - - return true; -} - -// --------------------------------------------------------------------------- -void TProcessManager::EnumSections(HANDLE HProcess, BYTE * PProcessBase, IMAGE_SECTION_HEADER * Buffer, DWORD * Secnum) { - int i; - BYTE *_pBuf, *_pSection; - DWORD _peHdrOffset, _sz; - IMAGE_NT_HEADERS _ntHdr; - IMAGE_SECTION_HEADER _section; - - // Read offset of PE header - if (!ReadProcessMemory(HProcess, PProcessBase + 0x3C, &_peHdrOffset, sizeof(_peHdrOffset), &_sz)) - return; - // Read IMAGE_NT_HEADERS.OptionalHeader.BaseOfCode - if (!ReadProcessMemory(HProcess, PProcessBase + _peHdrOffset, &_ntHdr, sizeof(_ntHdr), &_sz)) - return; - - _pSection = PProcessBase + _peHdrOffset + 4+sizeof(_ntHdr.FileHeader) + _ntHdr.FileHeader.SizeOfOptionalHeader; - memset((BYTE*)&_section, 0, sizeof(_section)); - - *Secnum = _ntHdr.FileHeader.NumberOfSections; - _pBuf = (BYTE*)Buffer; - for (i = 0; i < _ntHdr.FileHeader.NumberOfSections; i++) { - if (!ReadProcessMemory(HProcess, _pSection + i*sizeof(_section), &_section, sizeof(_section), &_sz)) - return; - memmove(_pBuf, &_section, sizeof(_section)); - _pBuf += sizeof(_section); - } -} - -// --------------------------------------------------------------------------- -void TProcessManager::DumpProcess(DWORD PID, TMemoryStream * MemStream, DWORD * BoC, DWORD * PoC, DWORD * ImB) { - WORD _secNum; - DWORD _peHdrOffset, _sz, _sizeOfCode; - DWORD _resPhys, _dd; - BYTE* _buf; - BYTE _b[8]; - HANDLE _hProcess, _hSnapshot; - MODULEINFO _moduleInfo = {0}; - IMAGE_NT_HEADERS _ntHdr; - PROCESSENTRY32 _ppe; - MODULEENTRY32 _pme; - IMAGE_SECTION_HEADER _sections[64]; - HMODULE hMod; - DWORD ModulesNum; - - _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, PID); // 0x1F0FFF - if (_hProcess) { - - EnumProcessModules(_hProcess, &hMod, sizeof(hMod), &ModulesNum); - GetModuleInformation(_hProcess, hMod, &_moduleInfo, sizeof(_moduleInfo)); - - if (!_moduleInfo.lpBaseOfDll) { - throw Exception("Invalid process, PID: " + IntToStr((int)PID)); - } - ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + 0x3C, &_peHdrOffset, sizeof(_peHdrOffset), &_sz); - ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + _peHdrOffset, &_ntHdr, sizeof(_ntHdr), &_sz); - EnumSections(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll, _sections, &_sz); - MemStream->Clear(); - // Dump Header - _buf = new BYTE[_ntHdr.OptionalHeader.SizeOfHeaders]; - ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll, _buf, _ntHdr.OptionalHeader.SizeOfHeaders, &_sz); - MemStream->WriteBuffer(_buf, _ntHdr.OptionalHeader.SizeOfHeaders); - delete[]_buf; - if (_sizeOfCode < _sections[1].Misc.VirtualSize) - _sizeOfCode = _sections[1].Misc.VirtualSize; - else - _sizeOfCode = _ntHdr.OptionalHeader.SizeOfCode; - // !!! - MemStream->Clear(); - _buf = new BYTE[_ntHdr.OptionalHeader.SizeOfImage]; - ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll, _buf, _ntHdr.OptionalHeader.SizeOfImage, &_sz); - MemStream->WriteBuffer(_buf, _ntHdr.OptionalHeader.SizeOfImage); - delete[]_buf; - // !!! - /* - //Dump Code - _buf = new BYTE[_sizeOfCode]; - ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + _ntHdr.OptionalHeader.BaseOfCode, _buf, _sizeOfCode, &_sz); - MemStream->WriteBuffer(_buf, _sizeOfCode); - delete[] _buf; - //Find EP - //Dump Resources - MemStream->Seek(0, soFromEnd); - _buf = new BYTE[_ntHdr.OptionalHeader.DataDirectory[2].Size]; - ReadProcessMemory(_hProcess, (BYTE*)_moduleInfo.lpBaseOfDll + _ntHdr.OptionalHeader.DataDirectory[2].VirtualAddress, _buf, _ntHdr.OptionalHeader.DataDirectory[2].Size, &_sz); - _resPhys = MemStream->Size; - MemStream->WriteBuffer(_buf, _ntHdr.OptionalHeader.DataDirectory[2].Size); - delete[] _buf; - */ - // Correct PE Header - // Set SectionNum = 2 - MemStream->Seek(6 + _peHdrOffset, soBeginning); - _secNum = 2; - MemStream->WriteBuffer(&_secNum, sizeof(_secNum)); - // Set EP - // Set sections - MemStream->Seek(0xF8 + _peHdrOffset, soBeginning); - // "CODE" - memset(_b, 0, 8); - _b[0] = 'C'; - _b[1] = 'O'; - _b[2] = 'D'; - _b[3] = 'E'; - MemStream->WriteBuffer(_b, 8); - _dd = _sizeOfCode; - MemStream->WriteBuffer(&_dd, 4); // VIRTUAL_SIZE - _dd = _ntHdr.OptionalHeader.BaseOfCode; - MemStream->WriteBuffer(&_dd, 4); // RVA - _dd = _sizeOfCode; - MemStream->WriteBuffer(&_dd, 4); // PHYSICAL_SIZE - _dd = _ntHdr.OptionalHeader.SizeOfHeaders; - MemStream->WriteBuffer(&_dd, 4); // PHYSICAL_OFFSET - _dd = 0; - MemStream->WriteBuffer(&_dd, 4); // RELOC_PTR - MemStream->WriteBuffer(&_dd, 4); // LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4); // RELOC_NUM,LINENUM_NUM - _dd = 0x60000020; - MemStream->WriteBuffer(&_dd, 4); // FLAGS - /* - //"DATA" - memset(_b, 0, 8); _b[0] = 'D'; _b[1] = 'A'; _b[2] = 'T'; _b[3] = 'A'; - MemStream->WriteBuffer(_b, 8); - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//RVA - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET - MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR - MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM - _dd = 0xC0000040; - MemStream->WriteBuffer(&_dd, 4);//FLAGS - //"BSS" - memset(_b, 0, 8); _b[0] = 'B'; _b[1] = 'S'; _b[2] = 'S'; - MemStream->WriteBuffer(_b, 8); - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//RVA - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET - MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR - MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM - _dd = 0xC0000040; - MemStream->WriteBuffer(&_dd, 4);//FLAGS - //".idata" - memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'i'; _b[2] = 'd'; _b[3] = 'a'; _b[4] = 't'; _b[5] = 'a'; - MemStream->WriteBuffer(_b, 8); - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//RVA - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET - MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR - MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM - _dd = 0xC0000040; - MemStream->WriteBuffer(&_dd, 4);//FLAGS - //".tls" - memset(_b, 0, 8); _b[0] = '.'; _b[1] = 't'; _b[2] = 'l'; _b[3] = 's'; - MemStream->WriteBuffer(_b, 8); - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//RVA - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET - MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR - MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM - _dd = 0xC0000000; - MemStream->WriteBuffer(&_dd, 4);//FLAGS - //".rdata" - memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'r'; _b[2] = 'd'; _b[3] = 'a'; _b[4] = 't'; _b[5] = 'a'; - MemStream->WriteBuffer(_b, 8); - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//RVA - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET - MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR - MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM - _dd = 0x50000040; - MemStream->WriteBuffer(&_dd, 4);//FLAGS - //".reloc" - memset(_b, 0, 8); _b[0] = '.'; _b[1] = 'r'; _b[2] = 'e'; _b[3] = 'l'; _b[4] = 'o'; _b[5] = 'c'; - MemStream->WriteBuffer(_b, 8); - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//RVA - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_SIZE - MemStream->WriteBuffer(&_dd, 4);//PHYSICAL_OFFSET - MemStream->WriteBuffer(&_dd, 4);//RELOC_PTR - MemStream->WriteBuffer(&_dd, 4);//LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4);//RELOC_NUM,LINENUM_NUM - _dd = 0x50000040; - MemStream->WriteBuffer(&_dd, 4);//FLAGS - */ - // ".rsrc" - memset(_b, 0, 8); - _b[0] = '.'; - _b[1] = 'r'; - _b[2] = 's'; - _b[3] = 'r'; - _b[4] = 'c'; - MemStream->WriteBuffer(_b, 8); - _dd = _ntHdr.OptionalHeader.DataDirectory[2].Size; - MemStream->WriteBuffer(&_dd, 4); // VIRTUAL_SIZE - _dd = _ntHdr.OptionalHeader.DataDirectory[2].VirtualAddress; - MemStream->WriteBuffer(&_dd, 4); // RVA - _dd = _ntHdr.OptionalHeader.DataDirectory[2].Size; - MemStream->WriteBuffer(&_dd, 4); // PHYSICAL_SIZE - _dd = _resPhys; - MemStream->WriteBuffer(&_dd, 4); // PHYSICAL_OFFSET - _dd = 0; - MemStream->WriteBuffer(&_dd, 4); // RELOC_PTR - MemStream->WriteBuffer(&_dd, 4); // LINENUM_PTR - MemStream->WriteBuffer(&_dd, 4); // RELOC_NUM,LINENUM_NUM - _dd = 0x50000040; - MemStream->WriteBuffer(&_dd, 4); // FLAGS - /* - //Correct directories - MemStream->Seek(0x78 + _peHdrOffset, soFromBeginning); - //Export table - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VA - MemStream->WriteBuffer(&_dd, 4);//Size - //Import table - _dd = 0; - MemStream->WriteBuffer(&_dd, 4);//VA - MemStream->WriteBuffer(&_dd, 4);//Size - //Resource table - _dd = _ntHdr.OptionalHeader.SizeOfHeaders; - MemStream->WriteBuffer(&_dd, 4);//RVA - _dd = _ntHdr.OptionalHeader.DataDirectory[2].Size; - MemStream->WriteBuffer(&_dd, 4);//VIRTUAL_SIZE - */ - - TPEHeader::EvaluateInitTable((BYTE*)MemStream->Memory, MemStream->Size, _ntHdr.OptionalHeader.ImageBase + _ntHdr.OptionalHeader.SizeOfHeaders); - - CloseHandle(_hProcess); - } -} -// ---------------------------------------------------------------------------// --------------------------------------------------------------------------- diff --git a/Sources/Libs/ProcessManager.h b/Sources/Libs/ProcessManager.h deleted file mode 100644 index c57d573..0000000 --- a/Sources/Libs/ProcessManager.h +++ /dev/null @@ -1,38 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef ProcessManagerH -#define ProcessManagerH - -#include -#include -#include - -#include "PEheader.h" - -using namespace std; - -// --------------------------------------------------------------------------- - -struct TProcess { - DWORD Pid; - DWORD ImageSize; - DWORD EntryPoint; - DWORD BaseAddress; - String Name; -}; - -// --------------------------------------------------------------------------- -class TProcessManager { -private: - vector FList; - - void EnumSections(HANDLE HProcess, BYTE* PProcessBase, IMAGE_SECTION_HEADER* Buffer, DWORD* Secnum); - -public: - bool GenerateProcessList(); - void DumpProcess(DWORD PID, TMemoryStream* MemStream, DWORD* BoC, DWORD* PoC, DWORD* ImB); - - __property vector ProcessList = {read = FList}; -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Resources.cpp b/Sources/Libs/Resources.cpp deleted file mode 100644 index a262bc7..0000000 --- a/Sources/Libs/Resources.cpp +++ /dev/null @@ -1,1752 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Resources.h" -#include "Main.h" -#include "Misc.h" -#include "ProgressBar.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "perfgrap.h" -#include "cspin.h" -#include "cgauges.h" -#include "cdiroutl.h" -#include "ccalendr.h" -#include "pies.h" -// #pragma link "pies" - -/* - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #include - #include - */ - -int(__stdcall*fnGetDstSize)(BYTE*, int); -boolean(__stdcall*fnDecrypt)(BYTE*, int, BYTE*, int); - -extern TResourceInfo *ResInfo; -extern DWORD CodeBase; -extern PInfoRec *Infos; - -// --------------------------------------------------------------------------- -bool ClassesRegistered = false; - -RegClassInfo RegClasses[] = { -/* //Standard - {__classid(Forms::TFrame), "TFrame"}, - {__classid(Menus::TMainMenu), "TMainMenu"}, - {__classid(Menus::TPopupMenu), "TPopupMenu"}, - {__classid(TLabel), "TLabel"}, - {__classid(TEdit), "TEdit"}, - {__classid(TLabeledEdit), "TLabeledEdit"}, - {__classid(TMemo), "TMemo"}, - {__classid(TButton), "TButton"}, - {__classid(TCheckBox), "TCheckBox"}, - {__classid(TRadioButton), "TRadioButton"}, - {__classid(TListBox), "TListBox"}, - {__classid(TComboBox), "TComboBox"}, - {__classid(TScrollBar), "TScrollBar"}, - {__classid(TGroupBox), "TGroupBox"}, - {__classid(TRadioGroup), "TRadioGroup"}, - {__classid(TPanel), "TPanel"}, - {__classid(TActionList), "TActionList"}, - {__classid(TAction), "TAction"}, - {__classid(Stdactns::TEditCut), "TEditCut"}, - {__classid(Stdactns::TEditCopy), "TEditCopy"}, - {__classid(Stdactns::TEditPaste), "TEditPaste"}, - {__classid(Stdactns::TEditSelectAll), "TEditSelectAll"}, - {__classid(Stdactns::TEditUndo), "TEditUndo"}, - {__classid(Stdactns::TEditDelete), "TEditDelete"}, - {__classid(Stdactns::TWindowClose), "TWindowClose"}, - {__classid(Stdactns::TWindowCascade), "TWindowCascade"}, - {__classid(Stdactns::TWindowTileHorizontal), "TWindowTileHorizontal"}, - {__classid(Stdactns::TWindowTileVertical), "TWindowTileVertical"}, - {__classid(Stdactns::TWindowMinimizeAll), "TWindowMinimizeAll"}, - {__classid(Stdactns::TWindowArrange), "TWindowArrange"}, - {__classid(Stdactns::THelpContents), "THelpContents"}, - {__classid(Stdactns::THelpTopicSearch), "THelpTopicSearch"}, - {__classid(Stdactns::THelpOnHelp), "THelpOnHelp"}, - {__classid(Stdactns::THelpContextAction), "THelpContextAction"}, - {__classid(Stdactns::TFileOpen), "TFileOpen"}, - {__classid(Stdactns::TFileOpenWith), "TFileOpenWith"}, - {__classid(Stdactns::TFileSaveAs), "TFileSaveAs"}, - {__classid(Stdactns::TFilePrintSetup), "TFilePrintSetup"}, - {__classid(Stdactns::TFileExit), "TFileExit"}, - {__classid(Stdactns::TSearchFind), "TSearchFind"}, - {__classid(Stdactns::TSearchReplace), "TSearchReplace"}, - {__classid(Stdactns::TSearchFindFirst), "TSearchFindFirst"}, - {__classid(Stdactns::TSearchFindNext), "TSearchFindNext"}, - {__classid(Stdactns::TFontEdit), "TFontEdit"}, - {__classid(Stdactns::TColorSelect), "TColorSelect"}, - {__classid(Stdactns::TPrintDlg), "TPrintDlg"}, - //TRichEditxxx actions? - //TListControlXXX ? - {__classid(Extactns::TOpenPicture), "TOpenPicture"}, - {__classid(Extactns::TSavePicture), "TSavePicture"}, - //Additional - {__classid(Buttons::TBitBtn), "TBitBtn"}, - {__classid(Buttons::TSpeedButton), "TSpeedButton"}, - {__classid(Mask::TMaskEdit), "TMaskEdit"}, - {__classid(Grids::TStringGrid), "TStringGrid"}, - {__classid(Grids::TDrawGrid), "TDrawGrid"}, - {__classid(Extctrls::TImage), "TImage"}, - {__classid(Graphics::TPicture), "TPicture"}, - {__classid(Graphics::TBitmap), "TBitmap"}, - {__classid(Graphics::TGraphic), "TGraphic"}, - {__classid(Graphics::TMetafile), "TMetafile"}, - {__classid(Graphics::TIcon), "TIcon"}, - - {__classid(TShape), "TShape"}, - {__classid(TBevel), "TBevel"}, - {__classid(Forms::TScrollBox), "TScrollBox"}, - {__classid(TCheckListBox), "TCheckListBox"}, - {__classid(TSplitter), "TSplitter"}, - {__classid(TStaticText), "TStaticText"}, - {__classid(TControlBar), "TControlBar"}, - {__classid(Chart::TChart), "TChart"}, - {__classid(Series::TBarSeries), "TBarSeries"}, - {__classid(Series::THorizBarSeries), "THorizBarSeries"}, - {__classid(Series::TPointSeries), "TPointSeries"}, - {__classid(Series::TAreaSeries), "TAreaSeries"}, - {__classid(Series::TLineSeries), "TLineSeries"}, - {__classid(Series::TFastLineSeries), "TFastLineSeries"}, - {__classid(Series::TPieSeries), "TPieSeries"}, - {__classid(TColorBox), "TColorBox"}, - //Win32 - {__classid(TTabControl), "TTabControl"}, - {__classid(TPageControl), "TPageControl"}, - {__classid(TTabSheet), "TTabSheet"}, - {__classid(TImageList), "TImageList"}, - {__classid(TRichEdit), "TRichEdit"}, - {__classid(TTrackBar), "TTrackBar"}, - {__classid(TProgressBar), "TProgressBar"}, - {__classid(TUpDown), "TUpDown"}, - {__classid(THotKey), "THotKey"}, - {__classid(TAnimate), "TAnimate"}, - {__classid(TDateTimePicker), "TDateTimePicker"}, - {__classid(TMonthCalendar), "TMonthCalendar"}, - {__classid(TTreeView), "TTreeView"}, - {__classid(TListView), "TListView"}, - {__classid(THeaderControl), "THeaderControl"}, - {__classid(TStatusBar), "TStatusBar"}, - {__classid(TToolBar), "TToolBar"}, - {__classid(TToolButton), "TToolButton"}, - {__classid(TCoolBar), "TCoolBar"}, - {__classid(TComboBoxEx), "TComboBoxEx"}, - {__classid(TPageScroller), "TPageScroller"}, - //System - //__classid(TPaintBox), - {__classid(TMediaPlayer), "TMediaPlayer"}, - //Win 3.1 - {__classid(Tabs::TTabSet), "TTabSet"}, - {__classid(Outline::TOutline), "TOutline"}, - {__classid(Tabnotbk::TTabbedNotebook), "TTabbedNotebook"}, - {__classid(TNotebook), "TNotebook"}, - {__classid(TPage), "TPage"}, - {__classid(THeader), "THeader"}, - {__classid(TFileListBox), "TFileListBox"}, - {__classid(TDirectoryListBox), "TDirectoryListBox"}, - {__classid(TDriveComboBox), "TDriveComboBox"}, - {__classid(TFilterComboBox), "TFilterComboBox"}, - //Samples - {__classid(TPerformanceGraph), "TPerformanceGraph"}, - {__classid(TCSpinButton), "TCSpinButton"}, - {__classid(TTimerSpeedButton), "TTimerSpeedButton"}, - {__classid(TCSpinEdit), "TCSpinEdit"}, - {__classid(TColorGrid), "TColorGrid"}, - {__classid(TCGauge), "TCGauge"}, - {__classid(TCDirectoryOutline), "TCDirectoryOutline"}, - {__classid(TCCalendar), "TCCalendar"}, - {__classid(TPie), "TPie"}, - // - {__classid(TValueListEditor), "TValueListEditor"}, - // - {__classid(IdrDfmDefaultControl), "Default"}, - {0, 0} - */ }; - -// --------------------------------------------------------------------------- -__fastcall TDfm::TDfm() { - Open = 0; - Flags = 0; - ResName = ""; - Name = ""; - ClassName = ""; - MemStream = new TMemoryStream; - ParentDfm = 0; - Events = new TList; - Components = new TList; - Form = 0; - Loader = 0; -} - -// --------------------------------------------------------------------------- -__fastcall TDfm::~TDfm() { - delete MemStream; - - int cnt = Events->Count; - for (int n = 0; n < cnt; n++) - delete(PEventInfo)Events->Items[n]; - delete Events; - - cnt = Components->Count; - for (int n = 0; n < cnt; n++) { - PComponentInfo cInfo = (PComponentInfo)Components->Items[n]; - if (cInfo->Events) { - for (int m = 0; m < cInfo->Events->Count; m++) - delete(PEventInfo)cInfo->Events->Items[m]; - delete cInfo->Events; - } - delete cInfo; - } - delete Components; - if (Form) - delete Form; - if (Loader) - delete Loader; -} - -// --------------------------------------------------------------------------- -bool __fastcall TDfm::IsFormComponent(String CompName) { - int cnt = Components->Count; - for (int n = 0; n < cnt; n++) { - PComponentInfo cInfo = (PComponentInfo)Components->Items[n]; - if (SameText(CompName, cInfo->Name)) - return true; - } - return false; -} - -// --------------------------------------------------------------------------- -__fastcall TResourceInfo::TResourceInfo() { - citadel = false; - Counter = 0; - hFormPlugin = 0; - FormPluginName = ""; - FormList = new TList; - Aliases = new TStringList; - - if (!ClassesRegistered) { - for (int n = 0; ; n++) { - if (!RegClasses[n].RegClass) - break; - Classes::RegisterClass(RegClasses[n].RegClass); - } - ClassesRegistered = true; - } -} - -// --------------------------------------------------------------------------- -__fastcall TResourceInfo::~TResourceInfo() { - if (hFormPlugin) { - FreeLibrary(hFormPlugin); - hFormPlugin = 0; - } - int cnt = FormList->Count; - for (int n = 0; n < cnt; n++) { - TDfm* dfm = (TDfm*)FormList->Items[n]; - delete dfm; - } - - delete FormList; - delete Aliases; - -} - -// --------------------------------------------------------------------------- -int __fastcall AnalyzeSection(TDfm* Dfm, TStringList* FormText, int From, PComponentInfo CInfo, int objAlign) { - int n, pos, align; - String componentName, componentClass, eventName, procName; - - for (n = From; n < FormText->Count; n++) { - String line = FormText->Strings[n].Trim(); - if (line == "") - continue; - align = FormText->Strings[n].Pos(line); - - if (SameText(line, "end") && align == objAlign) - break; - - bool inherited = (line.Pos("inherited ") == 1); - - if (line.Pos("object ") == 1 || inherited) { - int pos = line.Pos(":"); - int end = line.Length(); - int tmp = line.Pos(" ["); // eg: object Label1: TLabel [1] - if (tmp) - end = tmp - 1; - int off = (inherited ? 10 : 7); - - // object Label1: TLabel - if (pos) { - componentName = line.SubString(off, pos - off).Trim(); - componentClass = line.SubString(pos + 1, end - pos).Trim(); - } - // object TLabel - else { - componentName = "_" + Val2Str4(ResInfo->Counter) + "_"; - ResInfo->Counter++; - componentClass = line.SubString(off, end - off + 1).Trim(); - } - - PComponentInfo cInfo = new ComponentInfo; - cInfo->Inherit = inherited; - cInfo->HasGlyph = false; - cInfo->Name = componentName; - cInfo->ClassName = componentClass; - cInfo->Events = new TList; - - Dfm->Components->Add((void*)cInfo); - - if (ResInfo->Aliases->IndexOf(cInfo->ClassName) == -1) - ResInfo->Aliases->Add(cInfo->ClassName); - - n = AnalyzeSection(Dfm, FormText, n + 1, cInfo, align); - } - // Events begins with "On" or "Action". But events of TDataSet may begin with no these prefixes!!! - if ((pos = line.Pos("=")) != 0 && ((line[1] == 'O' && line[2] == 'n') || (line.Pos("Action ") == 1))) { - eventName = line.SubString(1, pos - 1).Trim(); // Include "On" - procName = line.SubString(pos + 1, line.Length() - pos).Trim(); - PEventInfo eInfo = new EventInfo; - eInfo->EventName = eventName; - eInfo->ProcName = procName; - // Form itself - if (!CInfo) { - Dfm->Events->Add((void*)eInfo); - } - else { - CInfo->Events->Add((void*)eInfo); - } - } - // Has property Glyph? - if (line.Pos("Glyph.Data =") == 1) - CInfo->HasGlyph = true; - } - return n; -} - -// --------------------------------------------------------------------------- -bool __stdcall EnumResNameProcedure(int hModule, char* Type, char* Name, long Param) { - bool res; - TFilerFlags flags; - int position, srcSize, dstSize; - TDfm* dfm; - TStringList* formText; - TMemoryStream* ms; - TResourceStream* resStream; - String className, vmtName; - BYTE signature[4]; - - if (Type == RT_RCDATA || Type == RT_BITMAP) { - resStream = new TResourceStream(hModule, String(Name), String(Type).c_str()); - if (Type == RT_RCDATA) { - ms = new TMemoryStream; - ms->LoadFromStream(resStream); - res = true; - if (ResInfo->hFormPlugin) { - fnGetDstSize = (int(__stdcall*)(BYTE*, int))GetProcAddress(ResInfo->hFormPlugin, "GetDstSize"); - fnDecrypt = (boolean(__stdcall*)(BYTE*, int, BYTE*, int))GetProcAddress(ResInfo->hFormPlugin, "Decrypt"); - res = (fnGetDstSize && fnDecrypt); - if (res) { - srcSize = ms->Size; - dstSize = fnGetDstSize((BYTE*)ms->Memory, srcSize); - if (srcSize != dstSize) { - TMemoryStream *ds = new TMemoryStream; - ds->Size = dstSize; - res = fnDecrypt((BYTE*)ms->Memory, srcSize, (BYTE*)ds->Memory, dstSize); - ms->Size = dstSize; - ms->CopyFrom(ds, dstSize); - delete ds; - } - else { - res = fnDecrypt((BYTE*)ms->Memory, srcSize, (BYTE*)ms->Memory, dstSize); - } - } - if (res) { - BYTE *mp = (BYTE*)ms->Memory; - BYTE len = *(mp + 4); - res = (len == strlen(Name) && SameText(Name, String((char*)mp + 5, len))); - } - } - if (res) { - ms->Seek(0, soFromBeginning); - ms->Read(signature, 4); - if (signature[0] == 'T' && signature[1] == 'P' && signature[2] == 'F' && (signature[3] >= '0' && signature[3] <= '7')) { - if (signature[3] == '0') { - // Äîáàâëÿåì â ñïèñîê ðåñóðñîâ - dfm = new TDfm; - dfm->ResName = Name; - dfm->MemStream = ms; - - // Analyze text representation - formText = new TStringList; - ResInfo->GetFormAsText(dfm, formText); - - String line = formText->Strings[0]; - bool inherited = (line.Pos("inherited ") == 1); - if (inherited) - dfm->Flags |= FF_INHERITED; - if (line.Pos("object ") == 1 || inherited) { - int off = (inherited ? 10 : 7); - int pos = line.Pos(":"); - dfm->Name = line.SubString(off, pos - off).Trim(); - dfm->ClassName = line.SubString(pos + 1, line.Length() - pos).Trim(); - AnalyzeSection(dfm, formText, 1, 0, 1); - } - delete formText; - - ((TResourceInfo*)Param)->FormList->Add((void*)dfm); - } - else if (!ResInfo->citadel) { - ShowMessage("Citadel for Delphi detected, forms cannot be loaded"); - ResInfo->citadel = true; - } - } - else { - delete ms; - } - } - else { - delete ms; - } - } - else if (Type == RT_BITMAP) { - dfm = new TDfm; - dfm->ResName = Name; - dfm->MemStream->LoadFromStream(resStream); - ((TResourceInfo*)Param)->FormList->Add((void*)dfm); - } - delete resStream; - } - return true; -} - -// --------------------------------------------------------------------------- -bool __fastcall TResourceInfo::EnumResources(String FileName) { - citadel = false; - hFormPlugin = LoadLibrary(AnsiString(FMain_11011981->AppDir + "Plugins\\" + FormPluginName).c_str()); - HINSTANCE hInst = LoadLibraryEx(AnsiString(FileName).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); - if (hInst) { - // EnumResourceNames(hInst, RT_RCDATA, (int(__stdcall*)(HINSTANCE, const char*, char*, long))EnumResNameProcedure, (long)this); - EnumResourceNames(hInst, RT_RCDATA, (ENUMRESNAMEPROC)EnumResNameProcedure, (long)this); - FreeLibrary(hInst); - return true; - } - if (hFormPlugin) { - FreeLibrary(hFormPlugin); - hFormPlugin = 0; - } - return false; -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::ShowResources(TListBox* ListBox) { - ListBox->Clear(); - - int wid, maxwid = 0; - TCanvas *canvas = ListBox->Canvas; - int cnt = FormList->Count; - for (int n = 0; n < cnt; n++) { - TDfm *dfm = (TDfm*)FormList->Items[n]; - ListBox->Items->Add(dfm->ResName + " {" + dfm->Name + "}"); - wid = canvas->TextWidth(dfm->ResName); - if (wid > maxwid) - maxwid = wid; - } - ListBox->ScrollWidth = maxwid + 2; -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::GetFormAsText(TDfm* Dfm, TStrings* DstList) { - TMemoryStream *memStream = new TMemoryStream; - memStream->Size = Dfm->MemStream->Size; - Dfm->MemStream->Seek(0, soFromBeginning); - ObjectBinaryToText(Dfm->MemStream, memStream); - memStream->Seek(0, soFromBeginning); - DstList->LoadFromStream(memStream); - delete memStream; -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::GetBitmap(TDfm* Dfm, Graphics::TBitmap* DstBitmap) { - Dfm->MemStream->Seek(0, soFromBeginning); - DstBitmap->LoadFromStream(Dfm->MemStream); -} - -// --------------------------------------------------------------------------- -TDfm* __fastcall TResourceInfo::GetParentDfm(TDfm* Dfm) { - String parentName = GetParentName(Dfm->ClassName); - int cnt = FormList->Count; - for (int n = 0; n < cnt; n++) { - TDfm* dfm1 = (TDfm*)FormList->Items[n]; - if (SameText(dfm1->ClassName, parentName)) - return dfm1; - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::CloseAllForms() { - int cnt = FormList->Count; - for (int n = 0; n < cnt; n++) { - TDfm* dfm = (TDfm*)FormList->Items[n]; - if (dfm->Open == 2) { - if (dfm->Form && dfm->Form->Visible) - dfm->Form->Close(); - dfm->Form = 0; - dfm->Open = 1; - } - if (dfm->Open == 1) { - if (dfm->Loader) - delete dfm->Loader; - dfm->Form = 0; - dfm->Loader = 0; - dfm->Open = 0; - } - } - - // this is a must have call! - // it removes just closed form from the Screen->Forms[] list! - // and we'll not have a new form with name [old_name]_1 ! - Application->ProcessMessages(); -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::ReopenAllForms() { - int cnt = FormList->Count; - for (int n = 0; n < cnt; n++) { - TDfm* dfm = (TDfm*)FormList->Items[n]; - if (dfm->Open == 2) // still opened - { - if (dfm->Form && dfm->Form->Visible) { - String FormName = dfm->Form->Name; - dfm->Form->Close(); - - // this is a must have call! - // it removes just closed form from the Screen->Forms[] list! - // and we'll not have a new form with name [old_name]_1 ! - Application->ProcessMessages(); - - int frmIdx = -1; - TDfm* dfm = GetFormIdx(FormName, &frmIdx); - FMain_11011981->ShowDfm(dfm); - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::InitAliases() { - int cnt = Aliases->Count; - for (int n = 0; n < cnt; n++) { - String className = Aliases->Strings[n]; - if (!className.Pos("=")) { - String alias = ""; - try { - // TMetaClass *componentClass = FindClass(className); - } - catch (Exception& e) { - if (SameText(className, "TDBGrid")) - alias = "TStringGrid"; - else if (SameText(className, "TDBText")) - alias = "TLabel"; - else if (SameText(className, "TDBEdit")) - alias = "TEdit"; - else if (SameText(className, "TDBMemo")) - alias = "TMemo"; - else if (SameText(className, "TDBImage")) - alias = "TImage"; - else if (SameText(className, "TDBListBox")) - alias = "TListBox"; - else if (SameText(className, "TDBComboBox")) - alias = "TComboBox"; - else if (SameText(className, "TDBCheckBox")) - alias = "TCheckBox"; - else if (SameText(className, "TDBRadioGroup")) - alias = "TRadioGroup"; - else if (SameText(className, "TDBLookupListBox")) - alias = "TListBox"; - else if (SameText(className, "TDBLookupComboBox")) - alias = "TComboBox"; - else if (SameText(className, "TDBRichEdit")) - alias = "TRichEdit"; - else if (SameText(className, "TDBCtrlGrid")) - alias = "TStringGrid"; - else if (SameText(className, "TDBChart")) - alias = "TChart"; - // sample components are redirected to TCxxx components - else if (SameText(className, "TGauge")) - alias = "TCGauge"; - else if (SameText(className, "TSpinEdit")) - alias = "TCSpinEdit"; - else if (SameText(className, "TSpinButton")) - alias = "TCSpinButton"; - else if (SameText(className, "TCalendar")) - alias = "TCCalendar"; - else if (SameText(className, "TDirectoryOutline")) - alias = "TCDirectoryOutline"; - else if (SameText(className, "TShellImageList")) - alias = "TImageList"; // special case, if not handled- crash (eg:1st Autorun Express app) - else if (!GetClass(className)) { - if (IsInheritsByClassName(className, "TBasicAction")) - alias = "TAction"; - else if (IsInheritsByClassName(className, "TMainMenu")) - alias = "TMainMenu"; - else if (IsInheritsByClassName(className, "TPopupMenu")) - alias = "TPopupMenu"; - else if (IsInheritsByClassName(className, "TCustomLabel") || AnsiContainsText(className, "Label") // evristika - ) - alias = "TLabel"; - else if (IsInheritsByClassName(className, "TCustomEdit")) - alias = "TEdit"; - else if (IsInheritsByClassName(className, "TCustomMemo")) - alias = "TMemo"; - else if (IsInheritsByClassName(className, "TButton")) - alias = "TButton"; - else if (IsInheritsByClassName(className, "TCustomCheckBox")) - alias = "TCheckBox"; - else if (IsInheritsByClassName(className, "TRadioButton")) - alias = "TRadioButton"; - else if (IsInheritsByClassName(className, "TCustomListBox")) - alias = "TListBox"; - else if (IsInheritsByClassName(className, "TCustomComboBox")) - alias = "TComboBox"; - else if (IsInheritsByClassName(className, "TCustomGroupBox")) - alias = "TGroupBox"; - else if (IsInheritsByClassName(className, "TCustomRadioGroup")) - alias = "TRadioGroup"; - else if (IsInheritsByClassName(className, "TCustomPanel")) - alias = "TPanel"; - else if (IsInheritsByClassName(className, "TBitBtn")) - alias = "TBitBtn"; - else if (IsInheritsByClassName(className, "TSpeedButton")) - alias = "TSpeedButton"; - else if (IsInheritsByClassName(className, "TImage")) - alias = "TImage"; - else if (IsInheritsByClassName(className, "TImageList")) - alias = "TImageList"; - else if (IsInheritsByClassName(className, "TBevel")) - alias = "TBevel"; - else if (IsInheritsByClassName(className, "TSplitter")) - alias = "TSplitter"; - else if (IsInheritsByClassName(className, "TPageControl")) - alias = "TPageControl"; - else if (IsInheritsByClassName(className, "TToolBar")) - alias = "TToolBar"; - else if (IsInheritsByClassName(className, "TToolButton")) - alias = "TToolButton"; - else if (IsInheritsByClassName(className, "TCustomStatusBar")) - alias = "TStatusBar"; - else if (IsInheritsByClassName(className, "TDateTimePicker")) - alias = "TDateTimePicker"; - else if (IsInheritsByClassName(className, "TCustomListView")) - alias = "TListView"; - else if (IsInheritsByClassName(className, "TCustomTreeView")) - alias = "TTreeView"; - else - alias = "Default"; - } - } - if (alias != "") - Aliases->Strings[n] = className + "=" + alias; - } - } -} - -// --------------------------------------------------------------------------- -String __fastcall TResourceInfo::GetAlias(String ClassName) { - for (int n = 0; n < Aliases->Count; n++) { - if (SameText(ClassName, Aliases->Names[n])) - return Aliases->Values[ClassName]; - } - return ""; -} - -// --------------------------------------------------------------------------- -TDfm* __fastcall TResourceInfo::GetFormIdx(String FormName, int* idx) { - for (int n = 0; n < FormList->Count; n++) { - TDfm* dfm = (TDfm*)FormList->Items[n]; - // Find form - if (SameText(dfm->Name, FormName)) { - *idx = n; - return dfm; - } - } - *idx = -1; - return 0; -} - -// --------------------------------------------------------------------------- -TDfm* __fastcall TResourceInfo::GetFormByClassName(String ClassName) { - for (int n = 0; n < FormList->Count; n++) { - TDfm* dfm = (TDfm*)FormList->Items[n]; - // Find form - if (SameText(dfm->ClassName, ClassName)) - return dfm; - } - return 0; -} - -// --------------------------------------------------------------------------- -void __fastcall TResourceInfo::GetEventsList(String FormName, TList* Lst) { - int n, evCnt, evCnt1, compCnt, compCnt1, frmCnt; - PEventListItem item; - PInfoRec recN, recN1; - - TDfm* dfm = GetFormIdx(FormName, &n); - if (!dfm) - return; - - DWORD classAdr = GetClassAdr(dfm->ClassName); - recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; - // Form - // Inherited - begin fill list - if (dfm->Flags & FF_INHERITED) { - TDfm* parentDfm = GetParentDfm(dfm); - if (parentDfm) { - GetEventsList(parentDfm->Name, Lst); - int evCount = Lst->Count; - evCount = evCount; - } - } - if (dfm->Events->Count) { - TList* ev = dfm->Events; - evCnt = ev->Count; - for (int k = 0; k < evCnt; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - item = new EventListItem; - item->CompName = FormName; - item->EventName = eInfo->EventName; // eInfo->ProcName; - String methodName = dfm->ClassName + "." + eInfo->ProcName; - // Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà - PMethodRec recM = FMain_11011981->GetMethodInfo(recN, methodName); - item->Adr = (recM) ? recM->address : 0; - Lst->Add(item); - } - } - // Components - compCnt = dfm->Components->Count; - for (int m = 0; m < compCnt; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - if (!cInfo->Events->Count) - continue; - - TList* ev = cInfo->Events; - evCnt = ev->Count; - for (int k = 0; k < evCnt; k++) { - recN1 = recN; - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - item = new EventListItem; - item->CompName = cInfo->Name; - item->EventName = eInfo->EventName; // eInfo->ProcName; - String methodName = ""; - // Action - if (SameText(eInfo->EventName, "Action")) { - // Name eInfo->ProcName like FormName.Name - int dotpos = eInfo->ProcName.Pos("."); - if (dotpos) { - String moduleName = eInfo->ProcName.SubString(1, dotpos - 1); - String actionName = eInfo->ProcName.SubString(dotpos + 1, eInfo->ProcName.Length() - dotpos); - // Find form moduleName - frmCnt = FormList->Count; - for (int j = 0; j < frmCnt; j++) { - TDfm* dfm1 = (TDfm*)FormList->Items[j]; - if (SameText(dfm1->Name, moduleName)) { - classAdr = GetClassAdr(dfm1->ClassName); - recN1 = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; - // Find component actionName - compCnt1 = dfm1->Components->Count; - for (int r = 0; r < compCnt1; r++) { - PComponentInfo cInfo1 = (PComponentInfo)dfm1->Components->Items[r]; - if (SameText(cInfo1->Name, actionName)) { - // Find event OnExecute - TList* ev1 = cInfo1->Events; - evCnt1 = ev1->Count; - for (int i = 0; i < evCnt1; i++) { - PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; - if (SameText(eInfo1->EventName, "OnExecute")) { - methodName = dfm1->ClassName + "." + eInfo1->ProcName; - break; - } - } - break; - } - } - break; - } - } - } - else { - // Find component eInfo->ProcName - compCnt = dfm->Components->Count; - for (int r = 0; r < compCnt; r++) { - PComponentInfo cInfo1 = (PComponentInfo)dfm->Components->Items[r]; - if (SameText(cInfo1->Name, eInfo->ProcName)) { - // Find event OnExecute - TList* ev1 = cInfo1->Events; - evCnt1 = ev1->Count; - for (int i = 0; i < evCnt1; i++) { - PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; - if (SameText(eInfo1->EventName, "OnExecute")) { - methodName = dfm->ClassName + "." + eInfo1->ProcName; - break; - } - } - break; - } - } - } - } - else { - methodName = dfm->ClassName + "." + eInfo->ProcName; - } - // Find method address - PMethodRec recM = FMain_11011981->GetMethodInfo(recN1, methodName); - item->Adr = (recM) ? recM->address : 0; - Lst->Add(item); - } - } -} - -// --------------------------------------------------------------------------- -// IdrDfmReader -// --------------------------------------------------------------------------- -__fastcall IdrDfmReader::IdrDfmReader(TStream* Stream, int BufSize) : TReader(Stream, BufSize) { -} - -// --------------------------------------------------------------------------- -// TComponentEvents -// --------------------------------------------------------------------------- -__fastcall TComponentEvents::TComponentEvents(TCollection* Owner) : TCollectionItem(Owner) { - Component = 0; - FoundEvents = new TStringList(); - FoundEvents->Sorted = true; -} - -// --------------------------------------------------------------------------- -__fastcall TComponentEvents::~TComponentEvents() { - delete FoundEvents; -} - -// --------------------------------------------------------------------------- -// IdrDfmForm -// --------------------------------------------------------------------------- -__fastcall IdrDfmForm::IdrDfmForm(TComponent* Owner) : TForm(Owner) { - compsEventsList = 0; - current = 0; - evPopup = new TPopupMenu(0); - evPopup->AutoPopup = false; - evPopup->AutoHotkeys = maManual; - frmTree = 0; - - KeyPreview = true; -} - -// --------------------------------------------------------------------------- -__fastcall IdrDfmForm::IdrDfmForm(TComponent* Owner, int Dummy) : TForm(Owner, Dummy) { - compsEventsList = 0; - current = 0; - evPopup = new TPopupMenu(0); - evPopup->AutoPopup = false; - evPopup->AutoHotkeys = maManual; - frmTree = 0; - - KeyPreview = true; -} - -// --------------------------------------------------------------------------- -__fastcall IdrDfmForm::~IdrDfmForm() { - if (compsEventsList) - delete compsEventsList; - compsEventsList = 0; - delete evPopup; - if (frmTree) - delete frmTree; - frmTree = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::SetDesigning(bool value, bool SetChildren) { - TComponent::SetDesigning(value, SetChildren); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::CreateHandle() { - if (FormStyle == fsMDIChild) { - FormStyle = Vcl::Forms::fsNormal; - return; - } - - TForm::CreateHandle(); -} - -// --------------------------------------------------------------------------- -// this is required action as sometimes ShortCut from target exe could be same as ours... -void __fastcall IdrDfmForm::SetupControlResetShortcut(TComponent* component) { - TCustomAction* action = dynamic_cast(component); - if (action && action->ShortCut) - action->ShortCut = 0; - - TMenuItem* mi = dynamic_cast(component); - if (mi && mi->ShortCut) - mi->ShortCut = 0; -} - -// --------------------------------------------------------------------------- -// different fine-tuning and fixes for components of the DFM Forms -void __fastcall IdrDfmForm::SetupControls() { - TComponent* component = this; - TControl* control = dynamic_cast(this); - if (control) { - SetupControlHint(Name, control, GetShortHint(control->Hint)); - ((TMyControl*)control)->OnMouseDown = ControlMouseDown; - if (((TMyControl*)control)->PopupMenu) - ((TMyControl*)control)->PopupMenu = 0; - } - - TBasicAction* action = dynamic_cast(component); - if (action) - action->OnExecute = ActionExecute; - SetupControlResetShortcut(component); - - for (int n = 0; n < ComponentCount; n++) { - component = Components[n]; - const String curName = component->Name; - SetupControlResetShortcut(component); - - control = dynamic_cast(component); - if (control) { - SetupControlHint(Name, control, GetShortHint(control->Hint)); - control->Visible = true; - control->Enabled = true; - ((TMyControl*)control)->OnMouseDown = ControlMouseDown; - if (((TMyControl*)control)->PopupMenu) - ((TMyControl*)control)->PopupMenu = 0; - } - - if (TPageControl * pageControl = dynamic_cast(component)) { - if (pageControl->PageCount > 0) - pageControl->ActivePageIndex = pageControl->PageCount - 1; - } - - else if (TTabSheet* ts = dynamic_cast(component)) - ts->TabVisible = true; - - else if (TBasicAction* action = dynamic_cast(component)) - action->OnExecute = ActionExecute; - - else if (TMenuItem * mi = dynamic_cast(component)) { - SetupMenuItem(mi, Name); // we start from this form name - mi->Enabled = true; - } - - // else if(TProgressBar* pb = dynamic_cast(component)) - // FProgressBar->pb->Position = FProgressBar->pb->Max/3; - - // else if (TStatusBar* sb = dynamic_cast(component)) - // FProgressBar->sb->AutoHint = false; - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::ControlMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { - if (Button == mbRight) { - TControl* control = dynamic_cast(Sender); - if (control) { - evPopup->Items->Clear(); - ShowMyPopupMenu(Name, control->Name, true); - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::miClick(TObject* Sender) { - TMenuItem* mi = dynamic_cast(Sender); - if (mi->Tag) - FMain_11011981->ShowCode(mi->Tag, 0, -1, -1); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::ActionExecute(TObject* Sender) { - // note: this is stub, you shold not stop here..... - // if you are here -> smth not OK - int x = 10; - ++x; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::ShowMyPopupMenu(String FormName, String ControlName, bool show) { - int n; - TMenuItem *mi; - TDfm* dfm = ResInfo->GetFormIdx(FormName, &n); - if (!dfm) - return; - - DWORD classAdr = GetClassAdr(dfm->ClassName); - PInfoRec recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; - - // Ôîðìà? - if (SameText(dfm->Name, ControlName)) { - // Inherited - íà÷àëè çàïîëíÿòü ìåíþ - if (dfm->Flags & FF_INHERITED) { - TDfm* parentDfm = ResInfo->GetParentDfm(dfm); - if (parentDfm) - ShowMyPopupMenu(parentDfm->Name, parentDfm->Name, false); - //  êîíöå äîáàâëÿåì ðàçäåëèòåëü - mi = new TMenuItem(evPopup); - mi->Caption = "-"; - evPopup->Items->Add(mi); - } - - // Ïåðâàÿ ñòðîêà ìåíþ - íàçâàíèå êîíòðîëà - mi = new TMenuItem(evPopup); - mi->Caption = dfm->Name + "." + dfm->ClassName; - mi->Tag = classAdr; - mi->OnClick = miPopupClick; - evPopup->Items->Add(mi); - // Âòîðàÿ ñòðîêà ìåíþ - ðàçäåëèòåëü - mi = new TMenuItem(evPopup); - mi->Caption = "-"; - evPopup->Items->Add(mi); - - PInfoRec recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; - - TList* ev = dfm->Events; - for (int k = 0; k < ev->Count; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - mi = new TMenuItem(evPopup); - mi->Caption = eInfo->EventName + " = " + eInfo->ProcName; - String methodName = dfm->ClassName + "." + eInfo->ProcName; - // Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà - PMethodRec recM = FMain_11011981->GetMethodInfo(recN, methodName); - mi->Tag = (recM) ? recM->address : 0; - mi->OnClick = miPopupClick; - evPopup->Items->Add(mi); - } - if (show && evPopup->Items->Count) { - TPoint cursorPos; - GetCursorPos(&cursorPos); - evPopup->Popup(cursorPos.x, cursorPos.y); - } - return; - } - // Êîìïîíåíòà ôîðìû? - else { - // Inherited - íà÷àëè çàïîëíÿòü ìåíþ - if (dfm->Flags & FF_INHERITED) { - TDfm* parentDfm = ResInfo->GetParentDfm(dfm); - if (parentDfm) - ShowMyPopupMenu(parentDfm->Name, ControlName, false); - //  êîíöå äîáàâëÿåì ðàçäåëèòåëü - mi = new TMenuItem(evPopup); - mi->Caption = "-"; - evPopup->Items->Add(mi); - } - - for (int m = 0; m < dfm->Components->Count; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - // Íàøëè êîìïîíåíòó, êîòîðîé ïðèíàäëåæèò control - if (SameText(cInfo->Name, ControlName)) { - // ×èñòèì evPopup - evPopup->Items->Clear(); - // Ïåðâàÿ ñòðîêà ìåíþ - íàçâàíèå êîíòðîëà - mi = new TMenuItem(evPopup); - mi->Caption = cInfo->Name + "." + cInfo->ClassName; - mi->Tag = GetClassAdr(cInfo->ClassName); - mi->OnClick = miPopupClick; - evPopup->Items->Add(mi); - // Âòîðàÿ ñòðîêà ìåíþ - ðàçäåëèòåëü - mi = new TMenuItem(evPopup); - mi->Caption = "-"; - evPopup->Items->Add(mi); - - TList* ev = cInfo->Events; - for (int k = 0; k < ev->Count; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - mi = new TMenuItem(evPopup); - mi->Caption = eInfo->EventName + " = " + eInfo->ProcName; - String methodName = ""; - // Action - if (SameText(eInfo->EventName, "Action")) { - // Èìÿ eInfo->ProcName ìîæåò èìåòü âèä FormName.Name - int dotpos = eInfo->ProcName.Pos("."); - if (dotpos) { - String moduleName = eInfo->ProcName.SubString(1, dotpos - 1); - String actionName = eInfo->ProcName.SubString(dotpos + 1, eInfo->ProcName.Length() - dotpos); - // Èùåì ôîðìó moduleName - for (int j = 0; j < ResInfo->FormList->Count; j++) { - TDfm* dfm1 = (TDfm*)ResInfo->FormList->Items[j]; - if (SameText(dfm1->Name, moduleName)) { - classAdr = GetClassAdr(dfm1->ClassName); - recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; - // Èùåì êîìïîíåíòó actionName - for (int r = 0; r < dfm1->Components->Count; r++) { - PComponentInfo cInfo1 = (PComponentInfo)dfm1->Components->Items[r]; - if (SameText(cInfo1->Name, actionName)) { - // Èùåì ñîáûòèå OnExecute - TList* ev1 = cInfo1->Events; - for (int i = 0; i < ev1->Count; i++) { - PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; - if (SameText(eInfo1->EventName, "OnExecute")) { - methodName = dfm1->ClassName + "." + eInfo1->ProcName; - break; - } - } - break; - } - } - break; - } - } - } - else { - // Èùåì êîìïîíåíòó eInfo->ProcName - for (int r = 0; r < dfm->Components->Count; r++) { - PComponentInfo cInfo1 = (PComponentInfo)dfm->Components->Items[r]; - if (SameText(cInfo1->Name, eInfo->ProcName)) { - // Èùåì ñîáûòèå OnExecute - TList* ev1 = cInfo1->Events; - for (int i = 0; i < ev1->Count; i++) { - PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; - if (SameText(eInfo1->EventName, "OnExecute")) { - methodName = dfm->ClassName + "." + eInfo1->ProcName; - break; - } - } - break; - } - } - } - } - else { - methodName = dfm->ClassName + "." + eInfo->ProcName; - } - // Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà - PMethodRec recM = FMain_11011981->GetMethodInfo(recN, methodName); - mi->Tag = (recM) ? recM->address : 0; - mi->OnClick = miPopupClick; - evPopup->Items->Add(mi); - } - if (evPopup->Items->Count) { - TPoint cursorPos; - GetCursorPos(&cursorPos); - evPopup->Popup(cursorPos.x, cursorPos.y); - } - return; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::miPopupClick(TObject *Sender) { - TMenuItem* mi = (TMenuItem*)Sender; - DWORD Adr = mi->Tag; - if (Adr && IsValidImageAdr(Adr)) { - PInfoRec recN = GetInfoRec(Adr); - if (recN) { - if (recN->kind == ikVMT) - FMain_11011981->ShowClassViewer(Adr); - else - FMain_11011981->ShowCode(Adr, 0, -1, -1); - } - } - else - ShowMessage("Handler not found"); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::SetupControlHint(String FormName, TControl* Control, String InitHint) { - for (int n = 0; n < ResInfo->FormList->Count; n++) { - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - // Íàøëè ôîðìó, êîòîðîé ïðèíàäëåæèò control - if (SameText(dfm->Name, FormName)) { - String hint = InitHint; - // Ñàìà ôîðìà? - if (SameText(dfm->Name, Control->Name)) { - if (hint != "") - hint += "\n"; - hint += dfm->Name + ":" + dfm->ClassName; - - TList* ev = dfm->Events; - for (int k = 0; k < ev->Count; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - hint += "\n" + eInfo->EventName + " = " + eInfo->ProcName; - } - Control->Hint = hint; - Control->ShowHint = true; - return; - } - else { - for (int m = 0; m < dfm->Components->Count; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - // Íàøëè êîìïîíåíòó, êîòîðîé ïðèíàäëåæèò control - if (SameText(cInfo->Name, Control->Name)) { - if (hint != "") - hint += "\n"; - hint += cInfo->Name + ":" + cInfo->ClassName; - - TList* ev = cInfo->Events; - for (int k = 0; k < ev->Count; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - hint += "\n" + eInfo->EventName + " = " + eInfo->ProcName; - } - Control->Hint = hint; - Control->ShowHint = true; - return; - } - } - } - } - } -} - -// --------------------------------------------------------------------------- -// find menu item handler (inherited forms supported) -void __fastcall IdrDfmForm::SetupMenuItem(TMenuItem* mi, String searchName) { - bool menuFound = false; - bool formInherited = false; - TDfm* curDfm = 0; - - for (int n = 0; n < ResInfo->FormList->Count; n++) { - // as: I dont like this, maybe put TDfm* into IdrDfmForm? - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - - // Íàøëè ôîðìó, êîòîðîé ïðèíàäëåæèò control - if (SameText(dfm->Name, searchName)) { - curDfm = dfm; - formInherited = dfm->Flags & FF_INHERITED; - - for (int m = 0; m < dfm->Components->Count; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - - // Íàøëè êîìïîíåíòó, êîòîðîé ïðèíàäëåæèò mi - if (SameText(cInfo->Name, mi->Name)) { - DWORD classAdr = GetClassAdr(dfm->ClassName); - PInfoRec recN = (IsValidImageAdr(classAdr)) ? Infos[Adr2Pos(classAdr)] : 0; - - TList* ev = cInfo->Events; - for (int k = 0; k < ev->Count; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - // OnClick - String methodName = ""; - PMethodRec recM; - if (SameText(eInfo->EventName, "OnClick")) { - methodName = dfm->ClassName + "." + eInfo->ProcName; - // Èùåì àäðåñ ñîîòâåòñòâóþùåãî ìåòîäà - recM = FMain_11011981->GetMethodInfo(recN, methodName); - mi->Tag = (recM) ? recM->address : 0; - mi->OnClick = miPopupClick; - // mi->Enabled = true; - continue; - } - // Action - if (SameText(eInfo->EventName, "Action")) { - // Èùåì êîìïîíåíòó ñ èìåíåì eInfo->ProcName - for (int r = 0; r < dfm->Components->Count; r++) { - PComponentInfo cInfo1 = (PComponentInfo)dfm->Components->Items[r]; - if (SameText(cInfo1->Name, eInfo->ProcName)) { - // Èùåì ñîáûòèå OnExecute - TList* ev1 = cInfo1->Events; - for (int i = 0; i < ev1->Count; i++) { - PEventInfo eInfo1 = (PEventInfo)ev1->Items[i]; - if (SameText(eInfo1->EventName, "OnExecute")) { - methodName = dfm->ClassName + "." + eInfo1->ProcName; - recM = FMain_11011981->GetMethodInfo(recN, methodName); - mi->Tag = (recM) ? recM->address : 0; - mi->OnClick = miPopupClick; - // mi->Enabled = true; - break; - } - } - break; - } - } - } - } - menuFound = true; - return; - } - } - } - } - - if (!menuFound && formInherited && curDfm && curDfm->ParentDfm) { - searchName = curDfm->ParentDfm->Name; - // recursive call in the parent form, trying to find the menu handler... - SetupMenuItem(mi, searchName); - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::DoFindMethod(String& methodName) { - if (FOnFindMethod) - FOnFindMethod(this, getFormName(), methodName); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::CMDialogKey(TCMDialogKey& Message) { - // allows for example Ctrl+Tab in TabSheet - if (Message.CharCode != VK_ESCAPE) - TForm::Dispatch(&Message); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::MyFormShow(TObject *Sender) { - if (!frmTree) { - frmTree = new TIdrDfmFormTree_11011981(this); - int ScrWid = Screen->WorkAreaWidth; - int ScrHei = Screen->WorkAreaHeight; - int FrmWid = this->Width; - int FrmHei = this->Height; - int TrvWid = frmTree->Width; - int TrvHei = frmTree->Height; - int FrmLeft = (ScrWid - FrmWid) / 2; - - if (TrvWid < FrmLeft) - frmTree->Left = FrmLeft - TrvWid; - else - frmTree->Left = 0; - - frmTree->Top = (ScrHei - TrvHei) / 2; - frmTree->Show(); - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::MyFormClose(TObject *Sender, TCloseAction &Action) { - for (int n = 0; n < ResInfo->FormList->Count; n++) { - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - if (dfm->Open == 2) - dfm->Open = 1; - } - - // notify main window that form is closed (ugly ref to main form - refactor!) - ::SendMessage(FMain_11011981->Handle, WM_DFMCLOSED, 0, 0); // Post - - Action = caFree; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::MyFormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - switch (Key) { - case VK_ESCAPE: - Close(); - break; - case VK_F11: - if (frmTree) - frmTree->Show(); - break; - } - - Key = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::MyShortCutEvent(Messages::TWMKey &Msg, bool &Handled) { - if (VK_ESCAPE == Msg.CharCode) { - Close(); - Handled = true; - } -} - -// --------------------------------------------------------------------------- -String __fastcall IdrDfmForm::getFormName() { - return String("T") + originalClassName; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmForm::SetMyHandlers() { - OnShow = MyFormShow; - OnClose = MyFormClose; - OnKeyDown = MyFormKeyDown; - OnShortCut = MyShortCutEvent; -} - -// --------------------------------------------------------------------------- -// IdrDfmLoader -// --------------------------------------------------------------------------- -__fastcall IdrDfmLoader::IdrDfmLoader(TComponent* Owner) : TComponent(Owner) { - dfmForm = 0; - Counter = 0; - Current = 0; - CompsEventsList = new TCollection(__classid(TComponentEvents)); -} - -// --------------------------------------------------------------------------- -__fastcall IdrDfmLoader::~IdrDfmLoader() { - if (CompsEventsList) - delete CompsEventsList; - CompsEventsList = 0; -} - -// --------------------------------------------------------------------------- -TForm* __fastcall IdrDfmLoader::LoadForm(TStream* dfmStream, TDfm* dfm, bool loadingParent) { - dfmForm = 0; - dfmStream->Seek(0, soFromBeginning); - - if (dfm && dfm->ParentDfm) { - dfm->Loader = new IdrDfmLoader(0); - dfmForm = (IdrDfmForm*)dfm->Loader->LoadForm(dfm->ParentDfm->MemStream, dfm->ParentDfm, true); - delete dfm->Loader; - dfm->Loader = 0; - } - else { - dfmForm = new IdrDfmForm(Application, 1); - } - - dfmStream->Seek(0, soFromBeginning); - TReader* Reader = new IdrDfmReader(dfmStream, 4096); - - Reader->OnAncestorNotFound = AncestorNotFound; - Reader->OnFindComponentClass = FindComponentClass; - Reader->OnCreateComponent = CreateComponent; - Reader->OnFindMethod = FindMethod; - Reader->OnError = ReaderError; - Reader->OnSetName = SetComponentName; - Reader->OnReferenceName = DoReferenceName; - - Current = (TComponentEvents*)(CompsEventsList->Add()); - Current->Component = dfmForm; - - TFilerFlags Flags; - int ChildPos; - - try { - Reader->ReadSignature(); - Reader->ReadPrefix(Flags, ChildPos); - dfmForm->originalClassType = Reader->ReadStr(); - dfmForm->originalClassName = Reader->ReadStr(); - Reader->Position = 0; - - Reader->ReadRootComponent(dfmForm); - - dfmForm->Enabled = true; - dfmForm->Visible = false; - dfmForm->Position = poScreenCenter; - dfmForm->compsEventsList = CompsEventsList; - dfmForm->OnFindMethod = OnFindMethod; - dfmForm->SetMyHandlers(); - - dfmForm->SetDesigning(false, false); - if (!loadingParent) - dfmForm->SetupControls(); - - if (dfmForm->AlphaBlend) - dfmForm->AlphaBlendValue = 222; - - dfmForm->AutoSize = false; - dfmForm->WindowState = wsNormal; - dfmForm->FormStyle = fsStayOnTop; - dfmForm->FormState.Clear(); - - dfmForm->Constraints->MinWidth = 0; - dfmForm->Constraints->MinHeight = 0; - dfmForm->Constraints->MaxWidth = 0; - dfmForm->Constraints->MaxHeight = 0; - - dfmForm->HelpFile = ""; - CompsEventsList = 0; - } - catch (Exception &e) { - ShowMessage("DFM Load Error\r\n" + e.ClassName() + ": " + e.Message); - dfmForm = 0; - } - - delete Reader; - return dfmForm; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::AncestorNotFound(TReader* Reader, String ComponentName, TMetaClass* ComponentClass, TComponent* &Component) { - String s = ComponentClass->ClassName(); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::FindComponentClass(TReader* Reader, String ClassName, TMetaClass* &ComponentClass) { - try { - ComponentClass = FindClass(ClassName); - } - catch (Exception& e) { - lastClassAliasName = ClassName; - - String alias = ResInfo->GetAlias(ClassName); - for (int n = 0; ; n++) { - if (!RegClasses[n].RegClass) - break; - if (SameText(alias, RegClasses[n].ClassName)) { - ComponentClass = RegClasses[n].RegClass; - break; - } - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::CreateComponent(TReader* Reader, TMetaClass* ComponentClass, TComponent* &Component) { - Current = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::FindMethod(TReader* Reader, String MethodName, void* &Address, bool &Error) { - if (Current) { - IdrDfmReader* r = dynamic_cast(Reader); - if (r) - Current->FoundEvents->Add(r->PropName + "=" + MethodName); - } - - Error = false; - Address = 0; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::ReaderError(TReader* Reader, String Message, bool &Handled) { - // if something really wrong happened, in order to fix the - // "DFM Stream read error" - skip fault value! - if (AnsiEndsStr("Invalid property value", Message) || AnsiEndsStr("Unable to insert a line", Message) || AnsiContainsText(Message, "List index out of bounds")) { - // move back to a type position byte - Reader->Position -= 1; - // skip the unknown value for known property (eg: Top = 11.453, or bad Items for StringList) - Reader->SkipValue(); - } - - Handled = true; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::SetComponentName(TReader* Reader, TComponent* Component, String &Name) { - if (Name == "") { - Name = "_" + Val2Str4(Counter) + "_"; - Counter++; - } - - if (Current && Current->Component == Component) - return; - - IdrDfmDefaultControl* rc = dynamic_cast(Component); - if (rc) { - String mappedClassName; - try { - mappedClassName = - // IdrDfmClassNameAnalyzer::GetInstance().GetMapping(lastClassAliasName); - ResInfo->GetAlias(lastClassAliasName); - } - catch (...) { - } - - rc->SetClassName(lastClassAliasName, mappedClassName); - } - - Current = (TComponentEvents*)(CompsEventsList->Add()); - Current->Component = Component; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmLoader::DoReferenceName(TReader* Reader, String &Name) { - if (dfmForm) { - TComponent* Component = dfmForm->FindComponent(Name); - if (Component) { - IdrDfmDefaultControl* rc = dynamic_cast(Component); - if (rc) { - Name = ""; - } - } - } -} - -// --------------------------------------------------------------------------- -bool __fastcall IdrDfmLoader::HasGlyph(String ClassName) { - for (int n = 0; n < ResInfo->FormList->Count; n++) { - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - for (int m = 0; m < dfm->Components->Count; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - if (SameText(cInfo->ClassName, ClassName)) - return cInfo->HasGlyph; - } - } - return false; -} - -// --------------------------------------------------------------------------- -// IdrDfmDefaultControl -// --------------------------------------------------------------------------- -__fastcall IdrDfmDefaultControl::IdrDfmDefaultControl(TComponent* Owner) : TPanel(Owner) { - Color = clNone; - imgIcon = 0; -} - -// --------------------------------------------------------------------------- -bool IdrDfmDefaultControl::IsVisible() { - return (Width > 0 && Height > 0); -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmDefaultControl::ReadState(TReader* Reader) { - DisableAlign(); - - try { - Width = 24; - Height = 24; - TPanel::ReadState(Reader); - } - __finally - // catch(Exception& e) - { - EnableAlign(); - } - - /* wow, intersting case seen, D7: - - object WebDispatcher1: TWebDispatcher - OldCreateOrder = False - Actions = <> - Left = 888 - Top = 8 - Height = 0 - Width = 0 - end - - we are not happy with 0:0 sizes, lets correct - */ - - if (Width <= 0) - Width = 24; - if (Height <= 0) - Height = 24; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmDefaultControl::Loaded() { - TPanel::Loaded(); - - BorderStyle = bsNone; - if (Color == clNone) - Color = clBtnFace; -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmDefaultControl::Paint() { - Canvas->Brush->Color = Color; - Canvas->Brush->Style = bsClear; - Canvas->Pen->Color = clGray; - Canvas->Pen->Style = psDot; - Canvas->Rectangle(GetClientRect()); -} - -// --------------------------------------------------------------------------- -void IdrDfmDefaultControl::SetClassName(const String& name, const String& mappedName) { - originalClassName = name; - // as note: - // here we should have mapped class, eg: - // we have on form TMyOpenDialog component, it was mapped to TOpenDialog, - // so I expect to have a string "TOpenDialog in mappedName, not "Default" ! - - mappedClassName = name; - - String usedClassName = (mappedClassName.IsEmpty()) ? originalClassName : mappedClassName; - - if (HasIconForClass(usedClassName)) { - CreateImageIconForClass(usedClassName); - } -} - -// --------------------------------------------------------------------------- -bool IdrDfmDefaultControl::HasIconForClass(const String& name) { - return true; - // TBD: ask dll if it has specified icon for class - // right now it is implicitly done in CreateImageIconForClass() -} - -// --------------------------------------------------------------------------- -void IdrDfmDefaultControl::CreateImageIconForClass(const String& imgFile) { - static HINSTANCE hResLib = 0; - static bool IconsDllLoaded = false; - static bool IconsDllPresent = true; - if (!IconsDllPresent) - return; - - if (!IconsDllLoaded) { - hResLib = LoadLibrary("Icons.dll"); - IconsDllLoaded = IconsDllPresent = (hResLib != 0); - if (!IconsDllPresent) - return; - } - - imgIcon = new TImage(this); - // old way - read from .bmp files on disk - // imgIcon->Picture->LoadFromFile(imgFile); - try { - imgIcon->Picture->Bitmap->LoadFromResourceName((int)hResLib, imgFile.UpperCase()); - imgIcon->AutoSize = true; - imgIcon->Transparent = true; - imgIcon->Parent = this; - - // yes, we want same popup as our parent - // imgIcon->OnMouseDown = ImageMouseDown; - - // update our component size in a case picture has another size - if (Width != imgIcon->Picture->Bitmap->Width) - Width = imgIcon->Picture->Bitmap->Width; - if (Height != imgIcon->Picture->Bitmap->Height) - Height = imgIcon->Picture->Bitmap->Height; - - } - catch (Exception& e) { - // icon not found or other error - free the image! - imgIcon->Parent = 0; - delete imgIcon; - imgIcon = 0; - } -} - -// --------------------------------------------------------------------------- -void __fastcall IdrDfmDefaultControl::ImageMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { - if (Button == mbRight) { - // Sender here is image, but we need this - replacing control! - if (Parent) - ((TMyControl*)Parent)->OnMouseDown(this, Button, Shift, X, Y); - } -} - -// --------------------------------------------------------------------------- -// IdrImageControl -// --------------------------------------------------------------------------- -__fastcall IdrImageControl::IdrImageControl(TComponent* Owner) : TImage(Owner) { -} - -// --------------------------------------------------------------------------- -void __fastcall IdrImageControl::Paint() { -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/Resources.h b/Sources/Libs/Resources.h deleted file mode 100644 index f076108..0000000 --- a/Sources/Libs/Resources.h +++ /dev/null @@ -1,218 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef ResourcesH -#define ResourcesH -// --------------------------------------------------------------------------- -// #include -// #include - -#include "UfrmFormTree.h" -// --------------------------------------------------------------------------- -typedef struct { - String CompName; // Component Name - String EventName; // Event Name - int Adr; // Event Address -} EventListItem, *PEventListItem; - -typedef struct { - TMetaClass *RegClass; - char *ClassName; -} RegClassInfo, *PRegClassInfo; - -typedef struct { - String EventName; // Event name (OnClose) - String ProcName; // Event handler name (CloseBtnClick) -} EventInfo, *PEventInfo; - -typedef struct { - bool Inherit; // Component is inherited - bool HasGlyph; // Component has property "Glyph" - String Name; // Component name - String ClassName; // Component class - TList *Events; // EventInfo list -} ComponentInfo, *PComponentInfo; - -class IdrDfmLoader; - -#define FF_INHERITED 1 -#define FF_HASNOTEBOOK 2 - -// Records to resource list -class TDfm { -public: - __fastcall TDfm(); - __fastcall ~TDfm(); - - BYTE Open; // 2 - form opened; 1 - form closed but loader not destroyed; 0 - form closed - BYTE Flags; // Form flags (see FF_...) - String ResName; // Resource name (ABOUTDIALOG) - String Name; // Form name (AboutDialog) - String ClassName; // Form class (TAboutDialog) - TMemoryStream *MemStream; // Memory Stream, containing Resource Data - TDfm *ParentDfm; // Parent form - TList *Events; // Form events list - TList *Components; // Form components list - TForm *Form; // Pointer to opened form - IdrDfmLoader *Loader; // Form loader - - bool __fastcall IsFormComponent(String CompName); -}; - -class TResourceInfo { -public: - __fastcall TResourceInfo(); - __fastcall ~TResourceInfo(); - void __fastcall GetFormAsText(TDfm* Dfm, TStrings* DstList); - bool __fastcall EnumResources(String FileName); - void __fastcall ShowResources(TListBox* ListBox); - void __fastcall GetBitmap(TDfm* Dfm, Graphics::TBitmap* DstBitmap); - TDfm* __fastcall GetParentDfm(TDfm* Dfm); - void __fastcall CloseAllForms(); - void __fastcall ReopenAllForms(); - void __fastcall InitAliases(); - String __fastcall GetAlias(String ClassName); - TDfm* __fastcall GetFormIdx(String FormName, int* idx); - TDfm* __fastcall GetFormByClassName(String ClassName); - void __fastcall GetEventsList(String FormName, TList* Lst); - - bool citadel; - int Counter; - HINSTANCE hFormPlugin; - String FormPluginName; - TList *FormList; // Form names list - TStringList *Aliases; // Aliases list -}; - -class TMyControl : public TControl { -public: - __property OnClick; - __property OnMouseDown; - __property PopupMenu; -}; - -class IdrDfmReader : public TReader { -public: - __fastcall IdrDfmReader(TStream* Stream, int BufSize); - - __property PropName; -}; - -class TComponentEvents : public TCollectionItem { -public: - __fastcall TComponentEvents(TCollection* Owner); - virtual __fastcall ~TComponentEvents(); - - TComponent *Component; - TStringList *FoundEvents; -}; - -typedef void __fastcall(__closure * TFindMethodSourceEvent)(TObject * Sender, const String & ClassName, const String & MethodName); - -class IdrDfmForm : public TForm { -public: - __fastcall IdrDfmForm(TComponent* Owner); - __fastcall IdrDfmForm(TComponent* Owner, int Dummy); - virtual __fastcall ~IdrDfmForm(); - - String originalClassName; - String originalClassType; - TComponentEvents *current; - TCollection *compsEventsList; - TPopupMenu* evPopup; - TIdrDfmFormTree_11011981* frmTree; - - void __fastcall SetupControls(); - void __fastcall SetupControlResetShortcut(TComponent* component); - void __fastcall SetDesigning(bool value, bool SetChildren); - void __fastcall SetMyHandlers(); - __property TFindMethodSourceEvent OnFindMethod = {read = FOnFindMethod, write = FOnFindMethod, default = 0}; - -protected: - virtual void __fastcall CreateHandle(); - void __fastcall SetupControlHint(String FormName, TControl* Control, String InitHint); - void __fastcall SetupMenuItem(TMenuItem* mi, String searchName); - void __fastcall ActionExecute(TObject* Sender); - void __fastcall miClick(TObject* Sender); - void __fastcall ControlMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y); - void __fastcall miPopupClick(TObject *Sender); - - BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(CM_DIALOGKEY, TCMDialogKey, CMDialogKey) END_MESSAGE_MAP(TForm) private : TFindMethodSourceEvent FOnFindMethod; - String __fastcall getFormName(); - void __fastcall DoFindMethod(String& methodName); - void __fastcall CMDialogKey(TCMDialogKey& Message); - void __fastcall MyFormShow(TObject *Sender); - void __fastcall MyFormClose(TObject *Sender, TCloseAction &Action); - void __fastcall MyFormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall MyShortCutEvent(Messages::TWMKey &Msg, bool &Handled); - void __fastcall ShowMyPopupMenu(String FormName, String ControlName, bool show); -}; - -class IdrDfmLoader : public TComponent { -public: - __fastcall IdrDfmLoader(TComponent* Owner); - virtual __fastcall ~IdrDfmLoader(); - - TForm* __fastcall LoadForm(TStream* dfmStream, TDfm* dfm, bool loadingParent = false); - __property TFindMethodSourceEvent OnFindMethod = {read = FOnFindMethod, write = SetOnFindMethod, default = 0}; - -protected: - int Counter; - TComponentEvents *Current; - TCollection *CompsEventsList; - String lastClassAliasName; - - void __fastcall AncestorNotFound(TReader* Reader, String ComponentName, TMetaClass* ComponentClass, TComponent* &Component); - void __fastcall ReaderError(TReader* Reader, String Message, bool &Handled); - void __fastcall FindComponentClass(TReader* Reader, String ClassName, TMetaClass* &ComponentClass); - void __fastcall CreateComponent(TReader* Reader, TMetaClass* ComponentClass, TComponent* &Component); - void __fastcall FindMethod(TReader* Reader, String MethodName, void* &Address, bool &Error); - void __fastcall SetComponentName(TReader* Reader, TComponent* Component, String &Name); - - void __fastcall DoReferenceName(TReader* Reader, String &Name); - void __fastcall SetOnFindMethod(TFindMethodSourceEvent method); - bool __fastcall HasGlyph(String ClassName); - -private: - IdrDfmForm* dfmForm; - TFindMethodSourceEvent FOnFindMethod; - - TComponent *FindComp(TComponent* Owner, String& compnay); -}; - -class IdrDfmDefaultControl : public TPanel { -public: - __fastcall IdrDfmDefaultControl(TComponent* Owner); - - bool IsVisible(); - void SetClassName(const String& name, const String& mappedName); - - String GetOrigClassName() { - return originalClassName; - } - -protected: - virtual void __fastcall Loaded(); - virtual void __fastcall ReadState(TReader* Reader); - virtual void __fastcall Paint(); - -private: - String originalClassName, mappedClassName; - - bool HasIconForClass(const String& name); - void CreateImageIconForClass(const String& imgFile); - - // image for std nonvisual controls (dialogs, etc) (dclstd60.bpl has images) - TImage* imgIcon; - - void __fastcall ImageMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y); - -}; - -class IdrImageControl : public TImage { -public: - __fastcall IdrImageControl(TComponent* Owner); - -protected: - virtual void __fastcall Paint(); -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Singleton.cpp b/Sources/Libs/Singleton.cpp deleted file mode 100644 index 74ad91d..0000000 --- a/Sources/Libs/Singleton.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// --------------------------------------------------------------------------- - -#pragma hdrstop - -#include "Singleton.h" -// #include -// --------------------------------------------------------------------------- -#pragma package(smart_init) - -// --------------------------------------------------------------------------- -template -TSingleton::TSingleton() { - assert(TSingleton::_instance == 0); - TSingleton::_instance = static_cast(this); -} - -// --------------------------------------------------------------------------- -template -T& TSingleton::Instance() { - if (TSingleton::_instance == 0) { - TSingleton::_instance = CreateInstance(); - } - return *(TSingleton::_instance); -} - -// --------------------------------------------------------------------------- -template -inline T* TSingleton::CreateInstance() { - return new T(); -} - -// --------------------------------------------------------------------------- -template -TSingleton::~TSingleton() { - if (Singleton::_instance != 0) { - delete TSingleton::_instance; - } - TSingleton::_instance = 0; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/Singleton.h b/Sources/Libs/Singleton.h deleted file mode 100644 index c28e36d..0000000 --- a/Sources/Libs/Singleton.h +++ /dev/null @@ -1,26 +0,0 @@ -// --------------------------------------------------------------------------- - -#ifndef SingletonH -#define SingletonH -// --------------------------------------------------------------------------- - -template -class TSingleton { -public: - static T& Instance(); - -protected: - virtual ~TSingleton(); - inline explicit TSingleton(); - -private: - static T* _instance; - - static T* CreateInstance(); -}; - -template -T* TSingleton::_instance = 0; - -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/Threads.cpp b/Sources/Libs/Threads.cpp deleted file mode 100644 index f9238e3..0000000 --- a/Sources/Libs/Threads.cpp +++ /dev/null @@ -1,3474 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Misc.h" -#include "Threads.h" -#pragma package(smart_init) -// --------------------------------------------------------------------------- -extern bool ProjectModified; -extern MKnowledgeBase KnowledgeBase; -extern TResourceInfo *ResInfo; - -// as: todo: remove all the global external dependencies -// all the required vars should be passed into the thread - -extern int dummy; -extern int DelphiVersion; -extern DWORD CurProcAdr; -extern DWORD CurUnitAdr; -extern bool ClassTreeDone; -extern SysProcInfo SysProcs[]; -extern SysProcInfo SysInitProcs[]; -extern BYTE *Code; -extern DWORD *Flags; -extern DWORD CodeSize; -extern DWORD CodeBase; -extern DWORD TotalSize; -extern PInfoRec *Infos; -extern TList *OwnTypeList; -extern int VmtSelfPtr; -extern int VmtInitTable; -extern int VmtInstanceSize; -extern int VmtParent; -extern int VmtClassName; -extern int VmtIntfTable; -extern int VmtAutoTable; -extern int VmtFieldTable; -extern int VmtMethodTable; -extern int VmtDynamicTable; -extern int VmtTypeInfo; -extern int VmtDestroy; -extern int UnitsNum; -extern TList *ExpFuncList; -extern TList *VmtList; -extern TList *Units; -extern DWORD EP; -extern DWORD HInstanceVarAdr; -extern int LastResStrNo; -extern MDisasm Disasm; - -// as: print every 10th address in status bar (analysis time booster) -static const int SKIPADDR_COUNT = 10; - -// --------------------------------------------------------------------------- -__fastcall TAnalyzeThread::TAnalyzeThread(TFMain_11011981* AForm, TFProgressBar* ApbForm, bool AllValues) : TThread(true) { - Priority = tpLower; - mainForm = AForm; - pbForm = ApbForm; - all = AllValues; - adrCnt = 0; -} - -// --------------------------------------------------------------------------- -__fastcall TAnalyzeThread::~TAnalyzeThread() { -} - -// --------------------------------------------------------------------------- -int __fastcall TAnalyzeThread::GetRetVal() { - return ReturnValue; -} - -// --------------------------------------------------------------------------- -// PopupMenu items!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// The Execute method is called when the thread starts -void __fastcall TAnalyzeThread::Execute() { - try { - if (all) { - // 1 - StrapSysProcs(); - ReturnValue = 1; - CurProcAdr = EP; - UpdateCode(); - // 2 - if (DelphiVersion != 2) { - FindRTTIs(); - ReturnValue = 2; - UpdateUnits(); - } - // 3 - if (DelphiVersion == 2) - FindVMTs2(); - else - FindVMTs(); - ReturnValue = 3; - UpdateVmtList(); - UpdateRTTIs(); - UpdateCode(); - // 4 - StrapVMTs(); - ReturnValue = 4; - UpdateCode(); - // 5 - ScanCode(); - ReturnValue = 5; - UpdateCode(); - // 6 - ScanVMTs(); - ReturnValue = 6; - UpdateVmtList(); - UpdateCode(); - UpdateShortClassViewer(); - // 7 - ScanConsts(); - ReturnValue = 7; - UpdateUnits(); - // 8 - ScanGetSetStoredProcs(); - ReturnValue = 8; - // 9 - FindStrings(); - ReturnValue = 9; - // 10 - AnalyzeCode1(); - ReturnValue = 10; - UpdateCode(); - UpdateXrefs(); - // 11 - ScanCode1(); - ReturnValue = 11; - UpdateCode(); - // 12 - PropagateClassProps(); - ReturnValue = 12; - UpdateCode(); - // 13 - FindTypeFields(); - ReturnValue = 13; - UpdateCode(); - // 14 - FindPrototypes(); - ReturnValue = 14; - UpdateCode(); - // 15 - AnalyzeCode2(true); - ReturnValue = 15; - UpdateCode(); - UpdateStrings(); - // 16 - AnalyzeDC(); - ReturnValue = 16; - UpdateCode(); - // 17 - AnalyzeCode2(false); - ReturnValue = 17; - UpdateCode(); - UpdateStrings(); - // 18 - AnalyzeDC(); - ReturnValue = 18; - UpdateCode(); - // 19 - AnalyzeCode2(false); - ReturnValue = LAST_ANALYZE_STEP; - UpdateCode(); - UpdateStrings(); - - UpdateBeforeClassViewer(); - } - // 20 - FillClassViewer(); - ReturnValue = LAST_ANALYZE_STEP + 1; - UpdateClassViewer(); - } - catch (Exception& e) { - Application->ShowException(&e); - } - - // as update main wnd about operation over - // only Post() here!) - async, otehrwise deadlock! - ::PostMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taFinished, 0); -} -// --------------------------------------------------------------------------- -const int PB_MAX_STEPS = 2048; - -int __fastcall TAnalyzeThread::StartProgress(int pbMaxCount, const String& sbText) { - int stepSize = 1; - int pbSteps = pbMaxCount / stepSize; - if (pbSteps * stepSize < pbMaxCount) - pbSteps++; - - if (pbMaxCount > PB_MAX_STEPS) { - stepSize = 256; - while (pbSteps > PB_MAX_STEPS) { - stepSize *= 2; - pbSteps = pbMaxCount / stepSize; - if (pbSteps * stepSize < pbMaxCount) - pbSteps++; - } - } - ThreadAnalysisData* startOperation = new ThreadAnalysisData(pbSteps, sbText); - ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taStartPrBar, (long)startOperation); // Post - - return stepSize - 1; -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateProgress() { - if (!Terminated) - ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdatePrBar, 0); // Post -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::StopProgress() { -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateStatusBar(int adr) { - // if (Terminated) - // throw Exception("Termination request2"); - if (!Terminated) { - ThreadAnalysisData* updateStatusBar = new ThreadAnalysisData(0, Val2Str8(adr)); - ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateStBar, (long)updateStatusBar); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateStatusBar(const String& sbText) { - // if (Terminated) - // throw Exception("Termination request3"); - if (!Terminated) { - ThreadAnalysisData* updateStatusBar = new ThreadAnalysisData(0, sbText); - ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateStBar, (long)updateStatusBar); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateAddrInStatusBar(DWORD adr) { - if (!Terminated) { - adrCnt++; - if (adrCnt == SKIPADDR_COUNT) { - UpdateStatusBar(adr); - adrCnt = 0; - } - } -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateUnits() { - if (!Terminated) { - long isLastStep = long(ReturnValue == LAST_ANALYZE_STEP); - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateUnits, isLastStep); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateRTTIs() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateRTTIs, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateVmtList() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateVmtList, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateStrings() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateStrings, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateCode() { - if (!Terminated) { - UpdateUnits(); - // cant use Post here, there are some global shared vars! - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateCode, 0); - } -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateXrefs() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateXrefs, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateShortClassViewer() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateShortClassViewer, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateClassViewer() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateClassViewer, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::UpdateBeforeClassViewer() { - if (!Terminated) - ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateBeforeClassViewer, 0); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::StrapSysProcs() { - int n, Idx, pos; - MProcInfo aInfo, *pInfo; - - WORD moduleID = KnowledgeBase.GetModuleID("System"); - for (n = 0; SysProcs[n].name && !Terminated; n++) { - Idx = KnowledgeBase.GetProcIdx(moduleID, SysProcs[n].name); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, &aInfo); - if (SysProcs[n].impAdr) { - mainForm->StrapProc(Adr2Pos(SysProcs[n].impAdr), Idx, pInfo, false, 6); - } - else { - pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); - if (pInfo && pos != -1) { - mainForm->StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); - } - } - } - } - } - - moduleID = KnowledgeBase.GetModuleID("SysInit"); - for (n = 0; SysInitProcs[n].name && !Terminated; n++) { - Idx = KnowledgeBase.GetProcIdx(moduleID, SysInitProcs[n].name); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, &aInfo); - pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); - if (pInfo && pos != -1) { - mainForm->StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); - } - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::FindRTTIs() { - BYTE paramCnt, numOps, methodKind, flags; - WORD dw, Count, methCnt; - DWORD typInfo, baseTypeAdr, dd, procSig; - int j, n, m, minValue, maxValue, elNum, pos, instrLen; - PInfoRec recN, recN1; - String name, unitName; - DISINFO DisInfo; - - int stepMask = StartProgress(CodeSize, "Find Types"); - - for (int i = 0; i < CodeSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - DWORD adr = *((DWORD*)(Code + i)); - if (IsValidImageAdr(adr) && adr == Pos2Adr(i) + 4) { - // Euristica - look at byte Code + i - 3 - may be case (jmp [adr + reg*4]) - instrLen = Disasm.Disassemble(Code + i - 3, (__int64)Pos2Adr(i) - 3, &DisInfo, 0); - if (instrLen > 3 && DisInfo.Branch && DisInfo.Offset == adr) - continue; - - DWORD typeAdr = adr - 4; - BYTE typeKind = Code[i + 4]; - if (typeKind == ikUnknown || typeKind > ikProcedure) - continue; - - BYTE len = Code[i + 5]; - if (!IsValidName(len, i + 6)) - continue; - - String TypeName = GetTypeName(adr); - UpdateStatusBar(TypeName); - /* - //Names that begins with '.' - if (TypeName[1] == '.') - { - String prefix; - switch (typeKind) - { - case ikEnumeration: - prefix = "_Enumeration_"; - break; - case ikArray: - prefix = "_Array_"; - break; - case ikDynArray: - prefix = "_DynArray_"; - break; - default: - prefix = form->GetUnitName(recU); - break; - } - TypeName = prefix + Val2Str0(recU->iniOrder) + "_" + TypeName.SubString(2, len); - } - */ - - n = i + 6 + len; - SetFlag(cfRTTI, i); - unitName = ""; - - switch (typeKind) { - case ikInteger: // 1 - n++; // ordType - n += 4; // MinVal - n += 4; // MaxVal - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikChar: // 2 - n++; // ordType - n += 4; // MinVal - n += 4; // MaxVal - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikEnumeration: // 3 - n++; // ordType - minValue = *((int*)(Code + n)); - n += 4; - maxValue = *((int*)(Code + n)); - n += 4; - // BaseType - baseTypeAdr = *((DWORD*)(Code + n)); - n += 4; - - if (baseTypeAdr == typeAdr) { - if (SameText(TypeName, "ByteBool") || SameText(TypeName, "WordBool") || SameText(TypeName, "LongBool")) { - minValue = 0; - maxValue = 1; - } - for (j = minValue; j <= maxValue; j++) { - len = Code[n]; - n += len + 1; - } - } - /* - //UnitName - len = Code[n]; - if (IsValidName(len, n + 1)) - { - unitName = String((char*)(Code + n + 1), len).Trim(); - SetUnitName(recU, unitName); - } - n += len + 1; - if (DelphiVersion >= 2010) - { - //AttrData - dw = *((WORD*)(Code + n)); n += dw; - } - */ - SetFlags(cfData, i, n - i); - break; - case ikFloat: // 4 - n++; // FloatType - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikString: // 5 - n++; // MaxLength - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikSet: // 6 - n += 1 + 4; // ordType+CompType - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikClass: // 7 - n += 4; // classVMT - n += 4; // ParentInfo - n += 2; // PropCount - // UnitName - len = Code[n]; - if (IsValidName(len, n + 1)) { - unitName = String((char*)(Code + n + 1), len).Trim(); - // FMain_11011981->SetUnitName(recU, unitName); - } - n += len + 1; - // PropData - Count = *((WORD*)(Code + n)); - n += 2; - for (j = 0; j < Count; j++) { - // TPropInfo - n += 26; - len = Code[n]; - n += len + 1; - } - if (DelphiVersion >= 2010) { - // PropDataEx - Count = *((WORD*)(Code + n)); - n += 2; - for (j = 0; j < Count; j++) { - // TPropInfoEx - // Flags - n++; - // Info - typInfo = *((DWORD*)(Code + n)); - n += 4; - pos = Adr2Pos(typInfo); - len = Code[pos + 26]; - SetFlags(cfData, pos, 27 + len); - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - if (DelphiVersion >= 2012) { - // ArrayPropCount - Count = *((WORD*)(Code + n)); - n += 2; - // ArrayPropData - for (j = 0; j < Count; j++) { - // Flags - n++; - // ReadIndex - n += 2; - // WriteIndex - n += 2; - // Name - len = Code[n]; - n += len + 1; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - } - } - SetFlags(cfData, i, n - i); - break; - case ikMethod: // 8 - // MethodKind - methodKind = Code[n]; - n++; // 0 (mkProcedure) or 1 (mkFunction) - paramCnt = Code[n]; - n++; - for (j = 0; j < paramCnt; j++) { - n++; // Flags - len = Code[n]; - n += len + 1; // ParamName - len = Code[n]; - n += len + 1; // TypeName - } - if (methodKind) { - // ResultType - len = Code[n]; - n += len + 1; - if (DelphiVersion > 6) { - // ResultTypeRef - n += 4; - } - } - if (DelphiVersion > 6) { - // CC - n++; - // ParamTypeRefs - n += 4 * paramCnt; - if (DelphiVersion >= 2010) { - // MethSig - procSig = *((DWORD*)(Code + n)); - n += 4; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - // Procedure Signature - if (procSig) { - if (IsValidImageAdr(procSig)) - pos = Adr2Pos(procSig); - else - pos = i + procSig; - m = 0; - // Flags - flags = Code[pos]; - m++; - if (flags != 0xFF) { - // CC - m++; - // ResultType - m += 4; - // ParamCount - paramCnt = Code[pos + m]; - m++; - for (j = 0; j < paramCnt; j++) { - // Flags - m++; - // ParamType - m += 4; - // Name - len = Code[pos + m]; - m += len + 1; - // AttrData - dw = *((WORD*)(Code + pos + m)); - m += dw; // ATR!! - } - } - SetFlags(cfData, pos, m); - } - } - } - SetFlags(cfData, i, n - i); - break; - case ikWChar: // 9 - n++; // ordType - n += 4; // MinVal - n += 4; // MaxVal - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikLString: // 0xA - // CodePage - if (DelphiVersion >= 2009) - n += 2; - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikWString: // 0xB - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikVariant: // 0xC - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikArray: // 0xD - n += 4; // Size - n += 4; // ElCount - n += 4; // ElType - if (DelphiVersion >= 2010) { - // DimCount - paramCnt = Code[n]; - n++; - for (j = 0; j < paramCnt; j++) { - // Dims - n += 4; - } - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikRecord: // 0xE - n += 4; // Size - elNum = *((int*)(Code + n)); - n += 4; // ManagedFldCount - for (j = 0; j < elNum; j++) { - n += 4; // TypeRef - n += 4; // FldOffset - } - - if (DelphiVersion >= 2010) { - numOps = Code[n]; - n++; // NumOps - for (j = 0; j < numOps; j++) // RecOps - { - n += 4; - } - elNum = *((int*)(Code + n)); - n += 4; // RecFldCnt - for (j = 0; j < elNum; j++) { - n += 4; // TypeRef - n += 4; // FldOffset - n++; // Flags - len = Code[n]; - n += len + 1; // Name - dw = *((WORD*)(Code + n)); - if (dw != 2) - dummy = 1; - n += dw; // ATR!! - } - dw = *((WORD*)(Code + n)); - if (dw != 2) - dummy = 1; - n += dw; // ATR!! - if (DelphiVersion >= 2012) { - methCnt = *((WORD*)(Code + n)); - n += 2; - for (j = 0; j < methCnt; j++) { - n++; // Flags - n += 4; // Code - len = Code[n]; - n += len + 1; // Name - // ProcedureSignature - // Flags - flags = Code[n]; - n++; - if (flags != 0xFF) { - // CC - n++; - // ResultType - n += 4; - // ParamCnt - paramCnt = Code[n]; - n++; - // Params - for (m = 0; m < paramCnt; m++) { - n++; // Flags - n += 4; // ParamType - len = Code[n]; - n += len + 1; // Name - dw = *((WORD*)(Code + n)); - if (dw != 2) - dummy = 1; - n += dw; // ATR!! - } - } - dw = *((WORD*)(Code + n)); - if (dw != 2) - dummy = 1; - n += dw; // ATR!! - } - } - } - SetFlags(cfData, i, n - i); - break; - case ikInterface: // 0xF - n += 4; // IntfParent - n++; // IntfFlags - n += 16; // GUID - // UnitName - len = Code[n]; - if (IsValidName(len, n + 1)) { - unitName = String((char*)(Code + n + 1), len).Trim(); - // FMain_11011981->SetUnitName(recU, unitName); - } - n += len + 1; - // PropCount - Count = *((WORD*)(Code + n)); - n += 2; - if (DelphiVersion >= 6) { - // RttiCount - dw = *((WORD*)(Code + n)); - n += 2; - if (dw != 0xFFFF) { - if (DelphiVersion >= 2010) { - for (j = 0; j < Count; j++) { - // Name - len = Code[n]; - n += len + 1; - // Kind - methodKind = Code[n]; - n++; - // CallConv - n++; - // ParamCount - paramCnt = Code[n]; - n++; - for (m = 0; m < paramCnt; m++) { - // Flags - n++; - // ParamName - len = Code[n]; - n += len + 1; - // TypeName - len = Code[n]; - n += len + 1; - // ParamType - n += 4; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - if (methodKind) { - // ResultTypeName - len = Code[n]; - n += len + 1; - if (len) { - // ResultType - n += 4; - //////////////////////////// Insert by Pigrecos - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - //////////////////////////// - } - } - } - } - else { - for (j = 0; j < Count; j++) { - // PropType - n += 4; - // GetProc - n += 4; - // SetProc - n += 4; - // StoredProc - n += 4; - // Index - n += 4; - // Default - n += 4; - // NameIndex - n += 2; - // Name - len = Code[n]; - n += len + 1; - } - } - } - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - } - SetFlags(cfData, i, n - i); - break; - case ikInt64: // 0x10 - n += 8; // MinVal - n += 8; // MaxVal - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikDynArray: // 0x11 - n += 4; // elSize - n += 4; // elType - n += 4; // varType - if (DelphiVersion >= 6) { - n += 4; // elType2 - // UnitName - len = Code[n]; - if (IsValidName(len, n + 1)) { - unitName = String((char*)(Code + n + 1), len).Trim(); - // FMain_11011981->SetUnitName(recU, unitName); - } - n += len + 1; - } - if (DelphiVersion >= 2010) { - // DynArrElType - n += 4; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikUString: // 0x12 - if (DelphiVersion >= 2010) { - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - } - SetFlags(cfData, i, n - i); - break; - case ikClassRef: // 0x13 - // InstanceType - n += 4; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - SetFlags(cfData, i, n - i); - break; - case ikPointer: // 0x14 - // RefType - n += 4; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - SetFlags(cfData, i, n - i); - break; - case ikProcedure: // 0x15 - // MethSig - procSig = *((DWORD*)(Code + n)); - n += 4; - // AttrData - dw = *((WORD*)(Code + n)); - n += dw; // ATR!! - SetFlags(cfData, i, n - i); - // Procedure Signature - if (procSig) { - if (IsValidImageAdr(procSig)) - pos = Adr2Pos(procSig); - else - pos = i + procSig; - m = 0; - // Flags - flags = Code[pos]; - m++; - if (flags != 0xFF) { - // CC - m++; - // ResultType - m += 4; - // ParamCount - paramCnt = Code[pos + m]; - m++; - for (j = 0; j < paramCnt; j++) { - // Flags+ParamType - m += 5; - // Name - len = Code[pos + m]; - m += len + 1; - // AttrData - dw = *((WORD*)(Code + pos + m)); - m += dw; // ATR!! - } - } - SetFlags(cfData, pos, m); - } - break; - } - - if (!Infos[i]) { - recN = new InfoRec(i, typeKind); - recN->SetName(TypeName); - } - PTypeRec recT = new TypeRec; - recT->kind = typeKind; - recT->adr = typeAdr; - if (unitName != "") - TypeName += " (" + unitName + ")"; - recT->name = TypeName; - OwnTypeList->Add(recT); - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::FindVMTs2() { - BYTE len; - WORD Num16; - int i, pos, bytes, _ap, _ap0; - DWORD Num32; - String TypeName; - - int stepMask = StartProgress(CodeSize, "Find Virtual Method Tables D2"); - - for (i = 0; i < CodeSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfCode | cfData, i)) - continue; - - DWORD selfPtr = *((DWORD*)(Code + i)); - if (selfPtr && !IsValidImageAdr(selfPtr)) - continue; - - DWORD initTableAdr = *((DWORD*)(Code + i + 4)); - if (initTableAdr) { - if (!IsValidImageAdr(initTableAdr)) - continue; - if (*(Code + pos) != 0xE) - continue; - pos = Adr2Pos(initTableAdr); - Num32 = *((DWORD*)(Code + pos + 5)); - if (Num32 > 10000) - continue; - } - - DWORD typeInfoAdr = *((DWORD*)(Code + i + 8)); - if (typeInfoAdr) { - if (!IsValidImageAdr(typeInfoAdr)) - continue; - // typeInfoAdr contains kind of type - pos = Adr2Pos(typeInfoAdr); - BYTE typeKind = *(Code + pos); - if (typeKind > tkVariant) - continue; - // len = *(Code + pos + 1); - // if (!IsValidName(len, pos + 2)) continue; - } - - DWORD fieldTableAdr = *((DWORD*)(Code + i + 0xC)); - if (fieldTableAdr) { - if (!IsValidImageAdr(fieldTableAdr)) - continue; - pos = Adr2Pos(fieldTableAdr); - Num16 = *((WORD*)(Code + pos)); - if (Num16 > 10000) - continue; - } - - DWORD methodTableAdr = *((DWORD*)(Code + i + 0x10)); - if (methodTableAdr) { - if (!IsValidImageAdr(methodTableAdr)) - continue; - pos = Adr2Pos(methodTableAdr); - Num16 = *((WORD*)(Code + pos)); - if (Num16 > 10000) - continue; - } - - DWORD dynamicTableAdr = *((DWORD*)(Code + i + 0x14)); - if (dynamicTableAdr) { - if (!IsValidImageAdr(dynamicTableAdr)) - continue; - pos = Adr2Pos(dynamicTableAdr); - Num16 = *((WORD*)(Code + pos)); - if (Num16 > 10000) - continue; - } - - DWORD classNameAdr = *((DWORD*)(Code + i + 0x18)); - if (!classNameAdr || !IsValidImageAdr(classNameAdr)) - continue; - - // _ap = Adr2Pos(classNameAdr); - // len = *(Code + _ap); - // if (!IsValidName(len, _ap + 1)) continue; - - DWORD instanceSize = *((DWORD*)(Code + i + 0x1C)); - if (!instanceSize) - continue; - - DWORD parentAdr = *((DWORD*)(Code + i + 0x20)); - if (parentAdr && !IsValidImageAdr(parentAdr)) - continue; - - DWORD defaultHandlerAdr = *((DWORD*)(Code + i + 0x24)); - if (defaultHandlerAdr && !IsValidImageAdr(defaultHandlerAdr)) - continue; - - DWORD newInstanceAdr = *((DWORD*)(Code + i + 0x28)); - if (newInstanceAdr && !IsValidImageAdr(newInstanceAdr)) - continue; - - DWORD freeInstanceAdr = *((DWORD*)(Code + i + 0x2C)); - if (freeInstanceAdr && !IsValidImageAdr(freeInstanceAdr)) - continue; - - DWORD destroyAdr = *((DWORD*)(Code + i + 0x30)); - if (destroyAdr && !IsValidImageAdr(destroyAdr)) - continue; - - DWORD classVMT = Pos2Adr(i) - VmtSelfPtr; - if (Adr2Pos(classVMT) < 0) - continue; - - int StopAt = GetStopAt(classVMT); - if (i + StopAt - classVMT - VmtSelfPtr >= CodeSize) - continue; - - _ap = Adr2Pos(classNameAdr); - if (_ap <= 0) - continue; - len = *(Code + _ap); - TypeName = String((char*)(Code + _ap + 1), len); - UpdateStatusBar(TypeName); - - // Add to TypeList - PTypeRec recT = new TypeRec; - recT->kind = ikVMT; - recT->adr = Pos2Adr(i); - recT->name = TypeName; - OwnTypeList->Add(recT); - - // Name already used - SetFlags(cfData, _ap, len + 1); - - if (!Infos[i]) { - PInfoRec recN = new InfoRec(i, ikVMT); - recN->SetName(TypeName); - } - // InitTable - if (initTableAdr) { - pos = Adr2Pos(initTableAdr); - bytes = 0; - pos++; - bytes++; // skip 0xE - pos++; - bytes++; // unknown byte - pos += 4; - bytes += 4; // unknown dd - Num32 = *((DWORD*)(Code + pos)); - bytes += 4; - - for (int m = 0; m < Num32; m++) { - // Type offset (Information about types already extracted) - bytes += 4; - // FieldOfs - bytes += 4; - } - // InitTable used - SetFlags(cfData, Adr2Pos(initTableAdr), bytes); - } - // FieldTable - if (fieldTableAdr) { - pos = Adr2Pos(fieldTableAdr); - bytes = 0; - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - // TypesTab - DWORD typesTab = *((DWORD*)(Code + pos)); - pos += 4; - bytes += 4; - - for (int m = 0; m < Num16; m++) { - // FieldOfs - pos += 4; - bytes += 4; - // idx - pos += 2; - bytes += 2; - len = Code[pos]; - pos++; - bytes++; - // name - pos += len; - bytes += len; - } - // FieldTable used - SetFlags(cfData, Adr2Pos(fieldTableAdr), bytes); - // Use TypesTab - Num16 = *((WORD*)(Code + Adr2Pos(typesTab))); - SetFlags(cfData, Adr2Pos(typesTab), 2 + Num16*4); - } - // MethodTable - if (methodTableAdr) { - pos = Adr2Pos(methodTableAdr); - bytes = 0; - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - - for (int m = 0; m < Num16; m++) { - // Length of Method Description - WORD skipNext = *((WORD*)(Code + pos)); - pos += skipNext; - bytes += skipNext; - } - // MethodTable used - SetFlags(cfData, Adr2Pos(methodTableAdr), bytes); - } - // DynamicTable - if (dynamicTableAdr) { - pos = Adr2Pos(dynamicTableAdr); - bytes = 0; - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - - for (int m = 0; m < Num16; m++) { - // Msg - bytes += 2; - // ProcAdr - bytes += 4; - } - // DynamicTable used - SetFlags(cfData, Adr2Pos(dynamicTableAdr), bytes); - } - - // DWORD StopAt = GetStopAt(classVMT); - // Èñïîëüçîâàëè âèðòóàëüíóþ òàáëèöó - SetFlags(cfData, i, StopAt - classVMT - VmtSelfPtr); - - PUnitRec recU = mainForm->GetUnit(classVMT); - if (recU) { - if (typeInfoAdr) // extract unit name - { - _ap0 = Adr2Pos(typeInfoAdr); - _ap = _ap0; - BYTE b = Code[_ap]; - _ap++; - if (b != 7) - continue; - len = Code[_ap]; - _ap++; - if (!IsValidName(len, _ap)) - continue; - _ap += len + 10; - len = Code[_ap]; - _ap++; - if (!IsValidName(len, _ap)) - continue; - String unitName = String((char*)(Code + _ap), len).Trim(); - _ap += len; - FMain_11011981->SetUnitName(recU, unitName); - // Use information about Unit - SetFlags(cfData, _ap0, _ap - _ap0); - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -// Collect information from VMT structure -void __fastcall TAnalyzeThread::FindVMTs() { - WORD Num16; - int bytes, pos, posv, EntryCount; - DWORD Num32; - - int stepMask = StartProgress(TotalSize, "Find Virtual Method Tables"); - - for (int i = 0; i < TotalSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfCode | cfData, i)) - continue; - DWORD adr = *((DWORD*)(Code + i)); // Points to vmt0 (VmtSelfPtr) - if (IsValidImageAdr(adr) && Pos2Adr(i) == adr + VmtSelfPtr) { - DWORD classVMT = adr; - DWORD StopAt = GetStopAt(classVMT); - // if (i + StopAt - classVMT - VmtSelfPtr >= CodeSize) continue; - - DWORD intfTableAdr = *((DWORD*)(Code + i + 4)); - if (intfTableAdr) { - if (!IsValidImageAdr(intfTableAdr)) - continue; - pos = Adr2Pos(intfTableAdr); - EntryCount = *((DWORD*)(Code + pos)); - if (EntryCount > 10000) - continue; - } - - DWORD autoTableAdr = *((DWORD*)(Code + i + 8)); - if (autoTableAdr) { - if (!IsValidImageAdr(autoTableAdr)) - continue; - pos = Adr2Pos(autoTableAdr); - EntryCount = *((DWORD*)(Code + pos)); - if (EntryCount > 10000) - continue; - } - - DWORD initTableAdr = *((DWORD*)(Code + i + 0xC)); - if (initTableAdr) { - if (!IsValidImageAdr(initTableAdr)) - continue; - pos = Adr2Pos(initTableAdr); - Num32 = *((DWORD*)(Code + pos + 6)); - if (Num32 > 10000) - continue; - } - - DWORD typeInfoAdr = *((DWORD*)(Code + i + 0x10)); - if (typeInfoAdr) { - if (!IsValidImageAdr(typeInfoAdr)) - continue; - // Ïî àäðåñó typeInfoAdr äîëæíû áûòü äàííûå î òèïå, íà÷èíàþùèåñÿ ñ îïðåäåëåííîé èíôîðìàöèè - pos = Adr2Pos(typeInfoAdr); - BYTE typeKind = *(Code + pos); - if (typeKind > ikProcedure) - continue; - // len = *(Code + pos + 1); - // if (!IsValidName(len, pos + 2)) continue; - } - - DWORD fieldTableAdr = *((DWORD*)(Code + i + 0x14)); - if (fieldTableAdr) { - if (!IsValidImageAdr(fieldTableAdr)) - continue; - pos = Adr2Pos(fieldTableAdr); - Num16 = *((WORD*)(Code + pos)); - if (Num16 > 10000) - continue; - } - - DWORD methodTableAdr = *((DWORD*)(Code + i + 0x18)); - if (methodTableAdr) { - if (!IsValidImageAdr(methodTableAdr)) - continue; - pos = Adr2Pos(methodTableAdr); - Num16 = *((WORD*)(Code + pos)); - if (Num16 > 10000) - continue; - } - - DWORD dynamicTableAdr = *((DWORD*)(Code + i + 0x1C)); - if (dynamicTableAdr) { - if (!IsValidImageAdr(dynamicTableAdr)) - continue; - pos = Adr2Pos(dynamicTableAdr); - Num16 = *((WORD*)(Code + pos)); - if (Num16 > 10000) - continue; - } - - DWORD classNameAdr = *((DWORD*)(Code + i + 0x20)); - if (!classNameAdr || !IsValidImageAdr(classNameAdr)) - continue; - - // n = Adr2Pos(classNameAdr); - // len = *(Code + n); - // if (!IsValidName(len, n + 1)) continue; - - DWORD parentAdr = *((DWORD*)(Code + i + 0x28)); - if (parentAdr && !IsValidImageAdr(parentAdr)) - continue; - - int n = Adr2Pos(classNameAdr); - BYTE len = Code[n]; - // if (!IsValidName(len, n + 1)) continue; - String TypeName = String((char*)(Code + n + 1), len); - UpdateStatusBar(TypeName); - - // Add to TypeList - PTypeRec recT = new TypeRec; - recT->kind = ikVMT; - recT->adr = Pos2Adr(i); - recT->name = TypeName; - OwnTypeList->Add(recT); - - // Name already use - SetFlags(cfData, n, len + 1); - - if (!GetInfoRec(Pos2Adr(i))) { - PInfoRec recN = new InfoRec(i, ikVMT); - recN->SetName(TypeName); - } - SetFlag(cfData, i); - - // IntfTable - DWORD vTableAdr; - - if (intfTableAdr) { - pos = Adr2Pos(intfTableAdr); - bytes = 0; - SetFlag(cfData | cfVTable, pos); - EntryCount = *((DWORD*)(Code + pos)); - pos += 4; - bytes += 4; - for (int m = 0; m < EntryCount; m++) { - // GUID - pos += 16; - bytes += 16; - vTableAdr = *((DWORD*)(Code + pos)); - pos += 4; - bytes += 4; - if (IsValidImageAdr(vTableAdr)) - SetFlag(cfData | cfVTable, Adr2Pos(vTableAdr)); - // IOffset - pos += 4; - bytes += 4; - if (DelphiVersion > 3) { - // ImplGetter - pos += 4; - bytes += 4; - } - } - // Intfs - if (DelphiVersion >= 2012) - bytes += EntryCount * 4; - - // Use IntfTable - SetFlags(cfData, Adr2Pos(intfTableAdr), bytes); - // Second pass (to use already set flags) - pos = Adr2Pos(intfTableAdr) + 4; - for (int m = 0; m < EntryCount; m++) { - // Skip GUID - pos += 16; - vTableAdr = *((DWORD*)(Code + pos)); - pos += 4; - // IOffset - pos += 4; - if (DelphiVersion > 3) { - // ImplGetter - pos += 4; - } - // Use VTable - if (IsValidImageAdr(vTableAdr)) { - DWORD vEnd = vTableAdr; - DWORD vStart = vTableAdr; - posv = Adr2Pos(vTableAdr); - bytes = 0; - for (int k = 0; ; k++) { - if (Pos2Adr(posv) == intfTableAdr) - break; - DWORD vAdr = *((DWORD*)(Code + posv)); - posv += 4; - bytes += 4; - if (vAdr && vAdr < vStart) - vStart = vAdr; - } - // Use VTable - SetFlags(cfData, Adr2Pos(vEnd), bytes); - // Leading always byte CC - vStart--; - // Use all refs - SetFlags(cfData, Adr2Pos(vStart), vEnd - vStart); - } - } - } - // AutoTable - if (autoTableAdr) { - pos = Adr2Pos(autoTableAdr); - bytes = 0; - EntryCount = *((DWORD*)(Code + pos)); - pos += 4; - bytes += 4; - for (int m = 0; m < EntryCount; m++) { - // DispID - pos += 4; - bytes += 4; - // NameAdr - DWORD pos1 = Adr2Pos(*((DWORD*)(Code + pos))); - pos += 4; - bytes += 4; - len = Code[pos1]; - // Use name - SetFlags(cfData, pos1, len + 1); - // Flags - pos += 4; - bytes += 4; - // ParamsAdr - pos1 = Adr2Pos(*((DWORD*)(Code + pos))); - pos += 4; - bytes += 4; - BYTE ParamCnt = Code[pos1 + 1]; - // Use Params - SetFlags(cfData, pos1, ParamCnt + 2); - // AddressAdr - pos += 4; - bytes += 4; - } - // Use AutoTable - SetFlags(cfData, Adr2Pos(autoTableAdr), bytes); - } - // InitTable - if (initTableAdr) { - pos = Adr2Pos(initTableAdr); - bytes = 0; - // Skip 0xE - pos++; - bytes++; - // Unknown byte - pos++; - bytes++; - // Unknown dword - pos += 4; - bytes += 4; - Num32 = *((DWORD*)(Code + pos)); - bytes += 4; - - for (int m = 0; m < Num32; m++) { - // TypeOfs (information about types is already extracted) - bytes += 4; - // FieldOfs - bytes += 4; - } - // Use InitTable - SetFlags(cfData, Adr2Pos(initTableAdr), bytes); - } - // FieldTable - if (fieldTableAdr) { - pos = Adr2Pos(fieldTableAdr); - bytes = 0; - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - // TypesTab - DWORD typesTab = *((DWORD*)(Code + pos)); - pos += 4; - bytes += 4; - - for (int m = 0; m < Num16; m++) { - // Offset - pos += 4; - bytes += 4; - // Idx - pos += 2; - bytes += 2; - // Name - len = Code[pos]; - pos++; - bytes++; - pos += len; - bytes += len; - } - // Use TypesTab - if (typesTab) { - Num16 = *((WORD*)(Code + Adr2Pos(typesTab))); - SetFlags(cfData, Adr2Pos(typesTab), 2 + Num16*4); - } - // Extended Information - if (DelphiVersion >= 2010) { - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - for (int m = 0; m < Num16; m++) { - // Flags - pos++; - bytes++; - // TypeRef - pos += 4; - bytes += 4; - // Offset - pos += 4; - bytes += 4; - // Name - len = Code[pos]; - pos++; - bytes++; - pos += len; - bytes += len; - // AttrData - WORD dw = *((WORD*)(Code + pos)); - pos += dw; - bytes += dw; // ATR!! - } - } - // Use FieldTable - SetFlags(cfData, Adr2Pos(fieldTableAdr), bytes); - } - // MethodTable - if (methodTableAdr) { - pos = Adr2Pos(methodTableAdr); - bytes = 0; - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - - for (int m = 0; m < Num16; m++) { - // Len - WORD skipBytes = *((WORD*)(Code + pos)); - pos += skipBytes; - bytes += skipBytes; - } - if (DelphiVersion >= 2010) { - Num16 = *((WORD*)(Code + pos)); - pos += 2; - bytes += 2; - for (int m = 0; m < Num16; m++) { - // MethodEntry - DWORD methodEntry = *((DWORD*)(Code + pos)); - pos += 4; - bytes += 4; - WORD skipBytes = *((WORD*)(Code + Adr2Pos(methodEntry))); - SetFlags(cfData, Adr2Pos(methodEntry), skipBytes); - // Flags - pos += 2; - bytes += 2; - // VirtualIndex - pos += 2; - bytes += 2; - } - if (DelphiVersion >= 2012) { - // VirtCount - bytes += 2; - } - } - // Use MethodTable - SetFlags(cfData, Adr2Pos(methodTableAdr), bytes); - } - // DynamicTable - if (dynamicTableAdr) { - pos = Adr2Pos(dynamicTableAdr); - bytes = 0; - Num16 = *((WORD*)(Code + pos)); - bytes += 2; - for (int m = 0; m < Num16; m++) { - // Msg+ProcAdr - bytes += 6; - } - // Use DynamicTable - SetFlags(cfData, Adr2Pos(dynamicTableAdr), bytes); - } - - // DWORD StopAt = GetStopAt(classVMT); - // Use Virtual Table - SetFlags(cfData, i, StopAt - classVMT - VmtSelfPtr); - - PUnitRec recU = mainForm->GetUnit(classVMT); - if (recU) { - adr = *((DWORD*)(Code + i - VmtSelfPtr + VmtTypeInfo)); - if (adr && IsValidImageAdr(adr)) { - // Extract unit name - pos = Adr2Pos(adr); - bytes = 0; - BYTE b = Code[pos]; - pos++; - bytes++; - if (b != 7) - continue; - len = Code[pos]; - pos++; - bytes++; - if (!IsValidName(len, pos)) - continue; - pos += len + 10; - bytes += len + 10; - len = Code[pos]; - pos++; - bytes++; - if (!IsValidName(len, pos)) - continue; - String unitName = String((char*)(Code + pos), len).Trim(); - bytes += len; - FMain_11011981->SetUnitName(recU, unitName); - // Use information about Unit (including previous dword) - SetFlags(cfData, Adr2Pos(adr) - 4, bytes + 4); - } - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::StrapVMTs() { - int stepMask = StartProgress(TotalSize, "Strap Virtual Method Tables"); - - MConstInfo cInfo; - for (int i = 0; i < TotalSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - PInfoRec recN = GetInfoRec(Pos2Adr(i)); - if (recN && recN->kind == ikVMT) { - String _name = recN->GetName(); - String ConstName = "_DV_" + _name; - WORD *uses = KnowledgeBase.GetConstUses(AnsiString(ConstName).c_str()); - int ConstIdx = KnowledgeBase.GetConstIdx(uses, AnsiString(ConstName).c_str()); - if (ConstIdx != -1) { - ConstIdx = KnowledgeBase.ConstOffsets[ConstIdx].NamId; - if (KnowledgeBase.GetConstInfo(ConstIdx, INFO_DUMP, &cInfo)) { - UpdateStatusBar(_name); - mainForm->StrapVMT(i + 4, ConstIdx, &cInfo); - } - } - if (uses) - delete[]uses; - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::FindTypeFields() { - int typeSize; - int stepMask = StartProgress(TotalSize, "Find Type Fields"); - - MTypeInfo atInfo; - MTypeInfo *tInfo = &atInfo; - - for (int i = 0; i < TotalSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - PInfoRec recN = GetInfoRec(Pos2Adr(i)); - if (recN && recN->kind == ikVMT) { - DWORD vmtAdr = Pos2Adr(i) - VmtSelfPtr; - PUnitRec recU = mainForm->GetUnit(vmtAdr); - if (recU) { - for (int u = 0; u < recU->names->Count && !Terminated; u++) { - WORD ModuleID = KnowledgeBase.GetModuleID(AnsiString(recU->names->Strings[u]).c_str()); - WORD *uses = KnowledgeBase.GetModuleUses(ModuleID); - // Find Type to extract information about fields - int TypeIdx = KnowledgeBase.GetTypeIdxByModuleIds(uses, AnsiString(recN->GetName()).c_str()); - if (TypeIdx != -1) { - TypeIdx = KnowledgeBase.TypeOffsets[TypeIdx].NamId; - if (KnowledgeBase.GetTypeInfo(TypeIdx, INFO_FIELDS, tInfo)) { - if (tInfo->Fields) { - UpdateStatusBar(tInfo->TypeName); - BYTE *p = tInfo->Fields; - FIELDINFO fInfo; - for (int n = 0; n < tInfo->FieldsNum; n++) { - fInfo.Scope = *p; - p++; - fInfo.Offset = *((int*)p); - p += 4; - fInfo.Case = *((int*)p); - p += 4; - WORD Len = *((WORD*)p); - p += 2; - fInfo.Name = String((char*)p, Len); - p += Len + 1; - Len = *((WORD*)p); - p += 2; - fInfo.Type = TrimTypeName(String((char*)p, Len)); - p += Len + 1; - recN->vmtInfo->AddField(0, 0, fInfo.Scope, fInfo.Offset, fInfo.Case, fInfo.Name, fInfo.Type); - } - } - } - } - if (uses) - delete[]uses; - } - } - } - } - StopProgress(); - - const int cntVmt = VmtList->Count; - stepMask = StartProgress(cntVmt, "Propagate VMT Names"); - for (int n = 0; n < cntVmt && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - PVmtListRec recV = (PVmtListRec)VmtList->Items[n]; - UpdateStatusBar(GetClsName(recV->vmtAdr)); - mainForm->PropagateVMTNames(recV->vmtAdr); - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -String __fastcall TAnalyzeThread::FindEvent(DWORD VmtAdr, String Name) { - DWORD adr = VmtAdr; - while (adr) { - PInfoRec recN = GetInfoRec(adr); - if (recN && recN->vmtInfo->fields) { - for (int n = 0; n < recN->vmtInfo->fields->Count; n++) { - PFIELDINFO fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; - if (SameText(fInfo->Name, Name)) - return fInfo->Type; - } - } - adr = GetParentAdr(adr); - } - return ""; -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::FindPrototypes() { - int n, m, k, r, idx, usesNum; - PInfoRec recN; - String importName, _name; - MProcInfo aInfo; - MProcInfo *pInfo = &aInfo; - MTypeInfo atInfo; - MTypeInfo *tInfo = &atInfo; - WORD uses[128]; - - int stepMask = StartProgress(CodeSize, "Find Import Prototypes"); - - for (n = 0; n < CodeSize && !Terminated; n += 4) { - if ((n & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfImport, n)) { - recN = GetInfoRec(Pos2Adr(n)); - _name = recN->GetName(); - int dot = _name.Pos("."); - int len = _name.Length(); - bool found = false; - BYTE *p; - WORD wlen; - // try find arguments - // FullName - importName = _name.SubString(dot + 1, len); - usesNum = KnowledgeBase.GetProcUses(AnsiString(importName).c_str(), uses); - for (m = 0; m < usesNum && !Terminated; m++) { - idx = KnowledgeBase.GetProcIdx(uses[m], AnsiString(importName).c_str()); - if (idx != -1) { - idx = KnowledgeBase.ProcOffsets[idx].NamId; - if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) { - if (pInfo->MethodKind == 'F') { - recN->kind = ikFunc; - recN->type = pInfo->TypeDef; - } - else if (pInfo->MethodKind == 'P') { - recN->kind = ikProc; - } - if (!recN->procInfo) - recN->procInfo = new InfoProcInfo; - - if (pInfo->Args) { - BYTE callKind = pInfo->CallKind; - - recN->procInfo->flags |= callKind; - - ARGINFO argInfo; - p = pInfo->Args; - int ss = 8; - for (k = 0; k < pInfo->ArgsNum; k++) { - FillArgInfo(k, callKind, &argInfo, &p, &ss); - recN->procInfo->AddArg(&argInfo); - } - found = true; - } - } - if (found) - break; - } - } - if (!found) { - // try short name - importName = _name.SubString(dot + 1, len - dot - 1); - usesNum = KnowledgeBase.GetProcUses(AnsiString(importName).c_str(), uses); - for (m = 0; m < usesNum && !Terminated; m++) { - idx = KnowledgeBase.GetProcIdx(uses[m], AnsiString(importName).c_str()); - if (idx != -1) { - idx = KnowledgeBase.ProcOffsets[idx].NamId; - if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) { - if (pInfo->MethodKind == 'F') { - recN->kind = ikFunc; - recN->type = pInfo->TypeDef; - } - else if (pInfo->MethodKind == 'P') { - recN->kind = ikProc; - } - if (!recN->procInfo) - recN->procInfo = new InfoProcInfo; - - if (pInfo->Args) { - BYTE callKind = pInfo->CallKind; - recN->procInfo->flags |= callKind; - - ARGINFO argInfo; - p = pInfo->Args; - int ss = 8; - for (k = 0; k < pInfo->ArgsNum; k++) { - FillArgInfo(k, callKind, &argInfo, &p, &ss); - recN->procInfo->AddArg(&argInfo); - } - found = true; - } - } - if (found) - break; - } - } - } - if (!found) { - // try without arguments - // FullName - importName = _name.SubString(dot + 1, len - dot); - usesNum = KnowledgeBase.GetProcUses(AnsiString(importName).c_str(), uses); - for (m = 0; m < usesNum && !Terminated; m++) { - idx = KnowledgeBase.GetProcIdx(uses[m], AnsiString(importName).c_str()); - if (idx != -1) { - idx = KnowledgeBase.ProcOffsets[idx].NamId; - if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) { - if (pInfo->MethodKind == 'F') { - recN->kind = ikFunc; - recN->type = pInfo->TypeDef; - } - else if (pInfo->MethodKind == 'P') { - recN->kind = ikProc; - } - found = true; - } - if (found) - break; - } - } - } - if (!found) { - // try without arguments - // ShortName - importName = _name.SubString(dot + 1, len - dot - 1); - usesNum = KnowledgeBase.GetProcUses(AnsiString(importName).c_str(), uses); - for (m = 0; m < usesNum && !Terminated; m++) { - idx = KnowledgeBase.GetProcIdx(uses[m], AnsiString(importName).c_str()); - if (idx != -1) { - idx = KnowledgeBase.ProcOffsets[idx].NamId; - if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) { - if (pInfo->MethodKind == 'F') { - recN->kind = ikFunc; - recN->type = pInfo->TypeDef; - } - else if (pInfo->MethodKind == 'P') { - recN->kind = ikProc; - } - found = true; - } - if (found) - break; - } - } - } - } - } - StopProgress(); - - StartProgress(ResInfo->FormList->Count, "Find Event Prototypes"); - - for (n = 0; n < ResInfo->FormList->Count && !Terminated; n++) { - UpdateProgress(); - TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; - String className = dfm->ClassName; - DWORD formAdr = GetClassAdr(className); - if (!formAdr) - continue; - recN = GetInfoRec(formAdr); - if (!recN || !recN->vmtInfo->methods) - continue; - - // The first: form events - TList* ev = dfm->Events; - for (m = 0; m < ev->Count && !Terminated; m++) { - PEventInfo eInfo = (PEventInfo)ev->Items[m]; - DWORD controlAdr = GetClassAdr(dfm->ClassName); - String typeName = FindEvent(controlAdr, "F" + eInfo->EventName); - if (typeName == "") - typeName = FindEvent(controlAdr, eInfo->EventName); - if (typeName != "") { - for (k = 0; k < recN->vmtInfo->methods->Count && !Terminated; k++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[k]; - if (SameText(recM->name, className + "." + eInfo->ProcName)) { - PInfoRec recN1 = GetInfoRec(recM->address); - if (recN1) { - String clsname = className; - while (1) { - if (KnowledgeBase.GetKBPropertyInfo(clsname, eInfo->EventName, tInfo)) { - recN1->kind = ikProc; - recN1->procInfo->flags |= PF_EVENT; - recN1->procInfo->DeleteArgs(); - // eax always Self - recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); - // transform declaration to arguments - recN1->procInfo->AddArgsFromDeclaration(AnsiString(tInfo->Decl).c_str(), 1, 0); - break; - } - clsname = GetParentName(clsname); - if (clsname == "") - break; - } - } - else { - ShowMessage("recN is Null"); - } - break; - } - } - } - } - // The second: components events - for (m = 0; m < dfm->Components->Count && !Terminated; m++) { - PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; - TList* ev = cInfo->Events; - for (k = 0; k < ev->Count && !Terminated; k++) { - PEventInfo eInfo = (PEventInfo)ev->Items[k]; - DWORD controlAdr = GetClassAdr(cInfo->ClassName); - String typeName = FindEvent(controlAdr, "F" + eInfo->EventName); - if (typeName == "") - typeName = FindEvent(controlAdr, eInfo->EventName); - if (typeName != "") { - for (r = 0; r < recN->vmtInfo->methods->Count && !Terminated; r++) { - PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[r]; - if (SameText(recM->name, className + "." + eInfo->ProcName)) { - PInfoRec recN1 = GetInfoRec(recM->address); - if (recN1) { - String clsname = className; - while (1) { - if (KnowledgeBase.GetKBPropertyInfo(clsname, eInfo->EventName, tInfo)) { - recN1->kind = ikProc; - recN1->procInfo->flags |= PF_EVENT; - recN1->procInfo->DeleteArgs(); - // eax always Self - recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); - // transform declaration to arguments - recN1->procInfo->AddArgsFromDeclaration(AnsiString(tInfo->Decl).c_str(), 1, 0); - break; - } - clsname = GetParentName(clsname); - if (clsname == "") - break; - } - } - else { - ShowMessage("recN is Null"); - } - break; - } - } - } - } - } - } - StopProgress(); -} -// --------------------------------------------------------------------------- -typedef struct { - bool used; - char *name; // èìÿ þíèòà - float matched; // ìàêñèìàëüíîå êîë-âî ñîâïàäåíèé - int maxno; // íîìåð þíèòà ñ ìàêñèìàëüíûì êîë-âîì ñîâïàäåíèé -} StdUnitInfo, *PStdUnitInfo; - -#define StdUnitsNum 7 -StdUnitInfo StdUnits[] = { - {false, "Types", 0.0, -1}, {false, "Multimon", 0.0, -1}, {false, "VarUtils", 0.0, -1}, {false, "StrUtils", 0.0, -1}, {false, "Registry", 0.0, -1}, {false, "IniFiles", 0.0, -1}, - {false, "Clipbrd", 0.0, -1}, {false, 0, 0.0, -1}}; - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::ScanCode() { - bool matched; - WORD moduleID; - DWORD Adr, iniAdr, finAdr, vmtAdr; - int FirstProcIdx, LastProcIdx, Num, DumpSize; - int i, n, m, k, r, u, Idx, fromPos, toPos, stepMask; - PUnitRec recU; - PInfoRec recN; - MProcInfo aInfo; - MProcInfo *pInfo = &aInfo; - MConstInfo acInfo; - MConstInfo *cInfo = &acInfo; - String className, unitName; - - StartProgress(UnitsNum, "Scan Initialization and Finalization procs"); - - // Begin with initialization and finalization procs - for (n = 0; n < UnitsNum && !Terminated; n++) { - UpdateProgress(); - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - iniAdr = recU->iniadr; - if (iniAdr && !recU->trivialIni) { - mainForm->AnalyzeProc(0, iniAdr); - - for (u = 0; u < recU->names->Count && !Terminated; u++) { - moduleID = KnowledgeBase.GetModuleID(AnsiString(recU->names->Strings[u]).c_str()); - if (moduleID == 0xFFFF) - continue; - - recU->kb = true; - // If unit is in knowledge base try to find proc Initialization - Idx = KnowledgeBase.GetProcIdx(moduleID, AnsiString(recU->names->Strings[u]).c_str()); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - matched = (MatchCode(Code + Adr2Pos(iniAdr), pInfo) && mainForm->StrapCheck(Adr2Pos(iniAdr), pInfo)); - if (matched) - mainForm->StrapProc(Adr2Pos(iniAdr), Idx, pInfo, true, pInfo->DumpSz); - } - } - } - } - } - finAdr = recU->finadr; - if (finAdr && !recU->trivialFin) { - mainForm->AnalyzeProc(0, finAdr); - - for (u = 0; u < recU->names->Count && !Terminated; u++) { - moduleID = KnowledgeBase.GetModuleID(AnsiString(recU->names->Strings[u]).c_str()); - if (moduleID == 0xFFFF) - continue; - - recU->kb = true; - // If unit is in knowledge base try to find proc Finalization - Idx = KnowledgeBase.GetProcIdx(moduleID, "Finalization"); - if (Idx != -1) { - Idx = KnowledgeBase.ProcOffsets[Idx].NamId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - matched = (MatchCode(Code + Adr2Pos(finAdr), pInfo) && mainForm->StrapCheck(Adr2Pos(finAdr), pInfo)); - if (matched) - mainForm->StrapProc(Adr2Pos(finAdr), Idx, pInfo, true, pInfo->DumpSz); - } - } - } - } - } - } - StopProgress(); - // EP - mainForm->AnalyzeProc(0, EP); - // Classes (methods, dynamics procedures, virtual methods) - stepMask = StartProgress(TotalSize, "Analyze Class Tables"); - for (n = 0; n < TotalSize && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->kind == ikVMT) { - vmtAdr = Pos2Adr(n); - UpdateStatusBar(GetClsName(vmtAdr)); - - mainForm->AnalyzeMethodTable(0, vmtAdr, &Terminated); - if (Terminated) - break; - mainForm->AnalyzeDynamicTable(0, vmtAdr, &Terminated); - if (Terminated) - break; - mainForm->AnalyzeVirtualTable(0, vmtAdr, &Terminated); - } - } - StopProgress(); - // Scan some standard units - StartProgress(StdUnitsNum, "Scan Standard Units: step1"); - for (r = 0; !Terminated; r++) { - UpdateProgress(); - if (!StdUnits[r].name) - break; - StdUnits[r].used = false; - StdUnits[r].matched = 0.0; - StdUnits[r].maxno = -1; - moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); - if (moduleID == 0xFFFF) - continue; - - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) - continue; - - for (n = 0; n < UnitsNum && !Terminated; n++) { - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - // Analyze units without name - if (!recU->names->Count) { - recU->matchedPercent = 0.0; - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - for (m = fromPos; m < toPos && !Terminated; m++) { - if (IsFlagSet(cfProcStart, m)) { - if (r != 5 && Pos2Adr(m) == recU->iniadr) - continue; - if (r != 5 && Pos2Adr(m) == recU->finadr) - continue; - - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - matched = false; - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) { - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - // If method of class, check that ClassName is found - // className = ExtractClassName(pInfo->ProcName); - // if (className == "" || GetOwnTypeByName(className)) - // { - recU->matchedPercent += 100.0 * pInfo->DumpSz / (toPos - fromPos + 1); - break; - // } - } - } - } - } - } - } - // float matchedPercent = 100.0*recU->matchedSize/(toPos - fromPos + 1); - if (recU->matchedPercent > StdUnits[r].matched) { - StdUnits[r].matched = recU->matchedPercent; - StdUnits[r].maxno = n; - } - } - } - } - StopProgress(); - StartProgress(StdUnitsNum, "Scan Standard Units: step2"); - for (r = 0; !Terminated; r++) { - UpdateProgress(); - if (!StdUnits[r].name) - break; - if (StdUnits[r].used) - continue; - if (StdUnits[r].matched < 50.0) - continue; - - moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); - if (moduleID == 0xFFFF) - continue; - - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) - continue; - - n = StdUnits[r].maxno; - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - // Analyze units without name - if (!recU->names->Count) { - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - for (m = fromPos; m < toPos && !Terminated; m++) { - if (IsFlagSet(cfProcStart, m)) { - if (r != 5 && Pos2Adr(m) == recU->iniadr) - continue; - if (r != 5 && Pos2Adr(m) == recU->finadr) - continue; - - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - matched = false; - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) { - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - // If method of class, check that ClassName is found - // className = ExtractClassName(pInfo->ProcName); - // if (className == "" || GetOwnTypeByName(className)) - // { - mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); - StdUnits[r].used = true; - break; - // } - } - } - } - } - } - } - } - } - StopProgress(); - for (n = 0; n < UnitsNum && !Terminated; n++) { - // UpdateProgress(); - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - // Delphi2 - it is possible that toPos = -1 - if (toPos == -1) - toPos = TotalSize; - - for (u = 0; u < recU->names->Count && !Terminated; u++) { - unitName = recU->names->Strings[u]; - moduleID = KnowledgeBase.GetModuleID(AnsiString(unitName).c_str()); - if (moduleID == 0xFFFF) - continue; - - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx, &DumpSize)) - continue; - - stepMask = StartProgress(toPos - fromPos + 1, "Scan Unit " + unitName + ": step1"); - - recU->kb = true; - for (m = fromPos, i = 0; m < toPos && !Terminated; m++, i++) { - if ((i & stepMask) == 0) - UpdateProgress(); - - if (!*(Code + m)) - continue; - if (IsFlagSet(cfProcStart, m) || !Flags[m]) { - if (Pos2Adr(m) == recU->iniadr && recU->trivialIni) - continue; - if (Pos2Adr(m) == recU->finadr && recU->trivialFin) - continue; - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) { - // Check code matching - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - // If method of class, check that ClassName is found - // className = ExtractClassName(pInfo->ProcName); - // if (className == "" || GetOwnTypeByName(className)) - // { - mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); - m += pInfo->DumpSz - 1; - break; - // } - } - } - } - } - } - } - StopProgress(); - } - } - // Òåïåðü ïîïðîáóåì îïÿòü ïðîéòèñü ïî VMT è ïîèñêàòü èõ â áàçå çíàíèé - stepMask = StartProgress(TotalSize, "Scan Units: step 2"); - for (n = 0; n < TotalSize && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->kind == ikVMT) { - String ConstName = "_DV_" + recN->GetName(); - Num = KnowledgeBase.GetConstIdxs(AnsiString(ConstName).c_str(), &Idx); - if (Num == 1) { - Adr = Pos2Adr(n); - recU = mainForm->GetUnit(Adr); - if (!recU || recU->trivial) - continue; - - if (!recU->names->Count) { - Idx = KnowledgeBase.ConstOffsets[Idx].NamId; - if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) { - moduleID = cInfo->ModuleID; - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) - continue; - - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - for (m = fromPos; m < toPos && !Terminated; m++) { - if (IsFlagSet(cfProcStart, m)) { - if (Pos2Adr(m) == recU->iniadr && recU->trivialIni) - continue; - if (Pos2Adr(m) == recU->finadr && recU->trivialFin) - continue; - - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - matched = false; - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) { - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - String unitName = KnowledgeBase.GetModuleName(moduleID); - FMain_11011981->SetUnitName(recU, unitName); - recU->kb = true; - mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); - break; - } - } - } - } - } - } - } - } - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::ScanCode1() { - bool matched; - WORD moduleID; - DWORD pos, Adr; - int FirstProcIdx, LastProcIdx, Num; - int n, m, k, r, u, Idx, fromPos, toPos; - PUnitRec recU; - PInfoRec recN; - MProcInfo aInfo; - MProcInfo *pInfo = &aInfo; - String className; - - StartProgress(UnitsNum, "Scan Code more..."); - for (n = 0; n < UnitsNum && !Terminated; n++) { - UpdateProgress(); - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - - for (u = 0; u < recU->names->Count && !Terminated; u++) { - moduleID = KnowledgeBase.GetModuleID(AnsiString(recU->names->Strings[u]).c_str()); - if (moduleID == 0xFFFF) - continue; - - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) - continue; - for (m = fromPos; m < toPos && !Terminated; m++) { - if (IsFlagSet(cfProcStart, m)) { - if (Pos2Adr(m) == recU->iniadr && recU->trivialIni) - continue; - if (Pos2Adr(m) == recU->finadr && recU->trivialFin) - continue; - - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) { - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - // If method of class, check that ClassName is found - // className = ExtractClassName(pInfo->ProcName); - // if (className == "" || GetOwnTypeByName(className)) - // { - mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); - break; - // } - } - } - } - } - } - } - } - } - StopProgress(); - StartProgress(StdUnitsNum, "Scan Standard Units more: step1"); - // Ïîïðîáóåì íåêîòîðûå ñòàíäàðòíûå þíèòû - for (r = 0; !Terminated; r++) { - UpdateProgress(); - if (!StdUnits[r].name) - break; - if (StdUnits[r].used) - continue; - StdUnits[r].matched = 0; - StdUnits[r].maxno = -1; - moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); - if (moduleID == 0xFFFF) - continue; - - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) - continue; - - for (n = 0; n < UnitsNum && !Terminated; n++) { - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - // Àíàëèçèðóåì íåïîèìåíîâàííûå þíèòû - if (!recU->names->Count) { - recU->matchedPercent = 0.0; - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - for (m = fromPos; m < toPos && !Terminated; m++) { - if (IsFlagSet(cfProcStart, m)) { - if (Pos2Adr(m) == recU->iniadr) - continue; - if (Pos2Adr(m) == recU->finadr) - continue; - - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - matched = false; - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) { - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - // If method of class, check that ClassName is found - // className = ExtractClassName(pInfo->ProcName); - // if (className == "" || GetOwnTypeByName(className)) - // { - recU->matchedPercent += 100.0 * pInfo->DumpSz / (toPos - fromPos + 1); - break; - // } - } - } - } - } - } - } - // float matchedPercent = 100.0*recU->matchedSize/(toPos - fromPos + 1); - if (recU->matchedPercent > StdUnits[r].matched) { - StdUnits[r].matched = recU->matchedPercent; - StdUnits[r].maxno = n; - } - } - } - } - StopProgress(); - StartProgress(StdUnitsNum, "Scan Standard Units more: step2"); - for (r = 0; !Terminated; r++) { - UpdateProgress(); - if (!StdUnits[r].name) - break; - if (StdUnits[r].used) - continue; - if (StdUnits[r].matched < 50.0) - continue; - - moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); - if (moduleID == 0xFFFF) - continue; - - if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) - continue; - - n = StdUnits[r].maxno; - recU = (UnitRec*)Units->Items[n]; - if (recU->trivial) - continue; - - // Àíàëèçèðóåì íåïîèìåíîâàííûå þíèòû - if (!recU->names->Count) { - fromPos = Adr2Pos(recU->fromAdr); - toPos = Adr2Pos(recU->toAdr); - for (m = fromPos; m < toPos && !Terminated; m++) { - if (IsFlagSet(cfProcStart, m)) { - if (Pos2Adr(m) == recU->iniadr) - continue; - if (Pos2Adr(m) == recU->finadr) - continue; - - recN = GetInfoRec(Pos2Adr(m)); - if (recN && recN->HasName()) - continue; - UpdateAddrInStatusBar(Pos2Adr(m)); - for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) { - Idx = KnowledgeBase.ProcOffsets[k].ModId; - if (!KnowledgeBase.IsUsedProc(Idx)) { - matched = false; - if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) { - matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); - if (matched) { - // If method of class, check that ClassName is found - // className = ExtractClassName(pInfo->ProcName); - // if (className == "" || GetOwnTypeByName(className)) - // { - mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); - StdUnits[r].used = true; - break; - // } - } - } - } - } - } - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::ScanVMTs() { - int stepMask = StartProgress(TotalSize, "Scan Virtual Method Tables"); - for (int n = 0; n < TotalSize && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->kind == ikVMT) { - DWORD vmtAdr = Pos2Adr(n); - String name = recN->GetName(); - UpdateStatusBar(name); - - mainForm->ScanFieldTable(vmtAdr); - if (Terminated) - break; - mainForm->ScanMethodTable(vmtAdr, name); - if (Terminated) - break; - mainForm->ScanVirtualTable(vmtAdr); - if (Terminated) - break; - mainForm->ScanDynamicTable(vmtAdr); - if (Terminated) - break; - - if (DelphiVersion != 2) { - mainForm->ScanIntfTable(vmtAdr); - mainForm->ScanAutoTable(vmtAdr); - if (Terminated) - break; - } - - mainForm->ScanInitTable(vmtAdr); - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::ScanConsts() { - WORD ModID; - int n, m, u, Bytes, ResStrIdx, pos, ResStrNum, ResStrNo; - DWORD adr, resid; - PUnitRec recU; - PInfoRec recN; - MResStrInfo arsInfo; - MResStrInfo *rsInfo = &arsInfo; - String uname; - char buf[1024]; - - if (Terminated) - return; - if (HInstanceVarAdr == 0xFFFFFFFF) - return; - - HINSTANCE hInst = LoadLibraryEx(AnsiString(mainForm->SourceFile).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); // DONT_RESOLVE_DLL_REFERENCES); - if (!hInst) - return; - - // Array of counters for units frequences - int *Counters = new int[KnowledgeBase.ModuleCount]; - - StartProgress(UnitsNum, "Scan Resource Strings"); - for (m = 0; m < UnitsNum && !Terminated; m++) { - UpdateProgress(); - recU = (PUnitRec)Units->Items[m]; - if (!recU) - continue; - - ModID = 0xFFFF; - // If module from KB load information about ResStrings - if (recU->names->Count) { - for (u = 0; u < recU->names->Count && !Terminated; u++) { - UpdateAddrInStatusBar(u); - ModID = KnowledgeBase.GetModuleID(AnsiString(recU->names->Strings[u]).c_str()); - // Åñëè èç áàçû çíàíèé, âûòàùèì èç íåå èíôîðìàöèþ î ResStr - if (ModID != 0xFFFF) { - for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) { - adr = *((DWORD*)(Code + n)); - resid = *((DWORD*)(Code + n + 4)); - - if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) { - recN = GetInfoRec(Pos2Adr(n)); - // If export at this position, delete InfoRec and create new (ikResString) - if (IsFlagSet(cfExport, n)) { - ClearFlag(cfProcStart, n); - delete recN; - recN = 0; - } - if (!recN) - recN = new InfoRec(n, ikResString); - else { - if (recN->kind == ikResString) - continue; - // may be ikData - if (!recN->rsInfo) - recN->rsInfo = new InfoResStringInfo; - } - recN->type = "TResStringRec"; - - // Set Flags - SetFlags(cfData, n, 8); - // Get Context - Bytes = LoadString(hInst, (UINT)resid, buf, 1024); - recN->rsInfo->value = String(buf, Bytes); - - ResStrIdx = KnowledgeBase.GetResStrIdx(ModID, buf); - if (ResStrIdx != -1) { - ResStrIdx = KnowledgeBase.ResStrOffsets[ResStrIdx].NamId; - if (KnowledgeBase.GetResStrInfo(ResStrIdx, 0, rsInfo)) { - if (!recN->HasName()) { - UpdateStatusBar(rsInfo->ResStrName); - recN->SetName(rsInfo->ResStrName); - } - } - } - else { - if (!recN->HasName()) { - recN->ConcatName("SResString" + String(LastResStrNo)); - LastResStrNo++; - } - } - } - } - } - // Else extract ResStrings from analyzed file - else { - for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) { - adr = *((DWORD*)(Code + n)); - resid = *((DWORD*)(Code + n + 4)); - - if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) { - recN = GetInfoRec(Pos2Adr(n)); - // If export at this position, delete InfoRec and create new (ikResString) - if (IsFlagSet(cfExport, n)) { - ClearFlag(cfProcStart, n); - delete recN; - recN = 0; - } - if (!recN) - recN = new InfoRec(n, ikResString); - else { - if (recN->kind == ikResString) - continue; - // may be ikData - if (!recN->rsInfo) - recN->rsInfo = new InfoResStringInfo; - } - recN->type = "TResStringRec"; - - // Set Flags - SetFlags(cfData, n, 8); - // Get Context - Bytes = LoadString(hInst, (UINT)resid, buf, 1024); - recN->rsInfo->value = String(buf, Bytes); - - if (!recN->HasName()) { - recN->ConcatName("SResString" + String(LastResStrNo)); - LastResStrNo++; - } - } - } - } - } - } - // If unit has no name check it is module of ResStrings - else { - UpdateProgress(); - memset(Counters, 0, KnowledgeBase.ModuleCount*sizeof(int)); - ResStrNum = 0; - - for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) { - adr = *((DWORD*)(Code + n)); - resid = *((DWORD*)(Code + n + 4)); - - if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) { - Bytes = LoadString(hInst, (UINT)resid, buf, 1024); - // Number of ReStrings in this module - ResStrNum++; - for (ResStrNo = 0; !Terminated;) { - ResStrIdx = KnowledgeBase.GetResStrIdx(ResStrNo, buf); - if (ResStrIdx == -1) - break; - ResStrNo = ResStrIdx + 1; - ResStrIdx = KnowledgeBase.ResStrOffsets[ResStrIdx].NamId; - if (KnowledgeBase.GetResStrInfo(ResStrIdx, 0, rsInfo)) { - Counters[rsInfo->ModuleID]++; - } - } - } - } - // What module has frequency >= ResStrNum - if (ResStrNum) { - for (n = 0; n < KnowledgeBase.ModuleCount && !Terminated; n++) { - if (Counters[n] >= 0.9 * ResStrNum) { - ModID = n; - break; - } - } - // Module is found - if (ModID != 0xFFFF) { - uname = KnowledgeBase.GetModuleName(ModID); - FMain_11011981->SetUnitName(recU, uname); - recU->kb = true; - - for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) { - adr = *((DWORD*)(Code + n)); - resid = *((DWORD*)(Code + n + 4)); - - if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) { - recN = GetInfoRec(Pos2Adr(n)); - // If export at this position, delete InfoRec and create new (ikResString) - if (IsFlagSet(cfExport, n)) { - ClearFlag(cfProcStart, n); - delete recN; - recN = 0; - } - if (!recN) - recN = new InfoRec(n, ikResString); - else { - if (recN->kind == ikResString) - continue; - // may be ikData - if (!recN->rsInfo) - recN->rsInfo = new InfoResStringInfo; - } - recN->type = "TResStringRec"; - - // Set Flags - SetFlags(cfData, n, 8); - // Get Context - Bytes = LoadString(hInst, (UINT)resid, buf, 1024); - recN->rsInfo->value = String(buf, Bytes); - - ResStrIdx = KnowledgeBase.GetResStrIdx(ModID, buf); - if (ResStrIdx != -1) { - ResStrIdx = KnowledgeBase.ResStrOffsets[ResStrIdx].NamId; - if (KnowledgeBase.GetResStrInfo(ResStrIdx, 0, rsInfo)) { - if (!recN->HasName()) { - UpdateStatusBar(rsInfo->ResStrName); - recN->SetName(rsInfo->ResStrName); - } - } - } - else { - if (!recN->HasName()) { - recN->ConcatName("SResString" + String(LastResStrNo)); - LastResStrNo++; - } - } - } - } - } - // Module not found, get ResStrings from analyzed file - else { - for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) { - adr = *((DWORD*)(Code + n)); - resid = *((DWORD*)(Code + n + 4)); - - if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) { - recN = GetInfoRec(Pos2Adr(n)); - // If export at this position, delete InfoRec and create new (ikResString) - if (IsFlagSet(cfExport, n)) { - ClearFlag(cfProcStart, n); - delete recN; - recN = 0; - } - if (!recN) - recN = new InfoRec(n, ikResString); - else { - if (recN->kind == ikResString) - continue; - // may be ikData - if (!recN->rsInfo) - recN->rsInfo = new InfoResStringInfo; - } - recN->type = "TResStringRec"; - - // Set Flags - SetFlags(cfData, n, 8); - // Get Context - Bytes = LoadString(hInst, (UINT)resid, buf, 1024); - recN->rsInfo->value = String(buf, Bytes); - - if (!recN->HasName()) { - recN->ConcatName("SResString" + String(LastResStrNo)); - LastResStrNo++; - } - } - } - } - } - } - } - FreeLibrary(hInst); - StopProgress(); - delete[]Counters; -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::ScanGetSetStoredProcs() { - for (int m = 0; m < OwnTypeList->Count && !Terminated; m++) { - PTypeRec recT = (PTypeRec)OwnTypeList->Items[m]; - if (recT->kind == ikClass) { - int n = Adr2Pos(recT->adr); - // SelfPtr - n += 4; - // typeKind - n++; - BYTE len = Code[n]; - n++; - // clsName - n += len; - - DWORD classVMT = *((DWORD*)(Code + n)); - n += 4; - PInfoRec recN1 = GetInfoRec(classVMT + VmtSelfPtr); - /* DWORD parentAdr = *((DWORD*)(Code + n)); */ n += 4; - WORD propCount = *((WORD*)(Code + n)); - n += 2; - // Skip unit name - len = Code[n]; - n++; - n += len; - // Real properties count - propCount = *((WORD*)(Code + n)); - n += 2; - - for (int i = 0; i < propCount && !Terminated; i++) { - DWORD propType = *((DWORD*)(Code + n)); - n += 4; - int posn = Adr2Pos(propType); - posn += 4; - posn++; // property type - len = Code[posn]; - posn++; - String fieldType = String((char*)(Code + posn), len); - - DWORD getProc = *((DWORD*)(Code + n)); - n += 4; - DWORD setProc = *((DWORD*)(Code + n)); - n += 4; - DWORD storedProc = *((DWORD*)(Code + n)); - n += 4; - // idx - n += 4; - // defval - n += 4; - // nameIdx - n += 2; - len = Code[n]; - n++; - String fieldName = String((char*)(Code + n), len); - n += len; - - int fieldOfs = -1; - if ((getProc & 0xFFFFFF00)) { - if ((getProc & 0xFF000000) == 0xFF000000) - fieldOfs = getProc & 0x00FFFFFF; - } - if ((setProc & 0xFFFFFF00)) { - if ((setProc & 0xFF000000) == 0xFF000000) - fieldOfs = setProc & 0x00FFFFFF; - } - if ((storedProc & 0xFFFFFF00)) { - if ((storedProc & 0xFF000000) == 0xFF000000) - fieldOfs = storedProc & 0x00FFFFFF; - } - if (recN1 && fieldOfs != -1) - recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, fieldName, fieldType); - } - } - } -} - -// --------------------------------------------------------------------------- -// LString -// RefCnt Length Data -// 0 4 8 -// recN (kind = ikLString, name = context) -// UString -// CodePage Word RefCnt Length Data -// 0 2 4 8 12 -// recN (kind = ikUString, name = context) -void __fastcall TAnalyzeThread::FindStrings() { - int i, len; - WORD codePage, elemSize; - DWORD refCnt; - PInfoRec recN; - - if (DelphiVersion >= 2009) { - int stepMask = StartProgress(CodeSize, "Scan UStrings"); - // Scan UStrings - for (i = 0; i < CodeSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfData, i)) - continue; - - codePage = *((WORD*)(Code + i)); - elemSize = *((WORD*)(Code + i + 2)); - if (!elemSize || elemSize > 4) - continue; - refCnt = *((DWORD*)(Code + i + 4)); - if (refCnt != 0xFFFFFFFF) - continue; - // len = wcslen((wchar_t*)(Code + i + 12)); - len = *((int*)(Code + i + 8)); - if (len <= 0 || len > 10000) - continue; - if (i + 12 + (len + 1) * elemSize >= CodeSize) - continue; - if (!Infos[i + 12]) { - UpdateAddrInStatusBar(Pos2Adr(i)); - recN = new InfoRec(i + 12, ikUString); - if (elemSize == 1) - recN->SetName(TransformString(Code + i + 12, len)); - else - recN->SetName(TransformUString(codePage, (wchar_t*)(Code + i + 12), len)); - } - // Align to 4 bytes - len = (12 + (len + 1) * elemSize + 3) & (-4); - SetFlags(cfData, i, len); - } - StopProgress(); - } - - int stepMask = StartProgress(CodeSize, "Scan LStrings"); - // Scan LStrings - for (i = 0; i < CodeSize && !Terminated; i += 4) { - if ((i & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfData, i)) - continue; - - refCnt = *((DWORD*)(Code + i)); - if (refCnt != 0xFFFFFFFF) - continue; - len = *((int*)(Code + i + 4)); - if (len <= 0 || len > 10000) - continue; - if (i + 8 + len + 1 >= CodeSize) - continue; - // Check last 0 - if (*(Code + i + 8 + len)) - continue; - // Check flags - // !!! - if (!Infos[i + 8]) { - UpdateAddrInStatusBar(Pos2Adr(i)); - recN = new InfoRec(i + 8, ikLString); - recN->SetName(TransformString(Code + i + 8, len)); - } - // Align to 4 bytes - len = (8 + len + 1 + 3) & (-4); - SetFlags(cfData, i, len); - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::AnalyzeCode1() { - String msg = "Analyzing step 1..."; - PUnitRec recU; - - StartProgress(UnitsNum, msg); - - // Initialization and Finalization procedures - for (int n = 0; n < UnitsNum && !Terminated; n++) { - UpdateProgress(); - recU = (UnitRec*)Units->Items[n]; - if (recU) { - DWORD iniAdr = recU->iniadr; - if (iniAdr) { - UpdateStatusBar(iniAdr); - mainForm->AnalyzeProc(1, iniAdr); - } - DWORD finAdr = recU->finadr; - if (finAdr) { - UpdateStatusBar(finAdr); - mainForm->AnalyzeProc(1, finAdr); - } - } - } - StopProgress(); - int stepMask = StartProgress(TotalSize, msg); - // EP - mainForm->AnalyzeProc(1, EP); - DWORD vmtAdr; - // Classes (methods, dynamics procedures, virtual methods) - for (int n = 0; n < TotalSize && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - PInfoRec recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->kind == ikVMT) { - vmtAdr = Pos2Adr(n); - UpdateAddrInStatusBar(vmtAdr); - - mainForm->AnalyzeMethodTable(1, vmtAdr, &Terminated); - if (Terminated) - break; - mainForm->AnalyzeDynamicTable(1, vmtAdr, &Terminated); - if (Terminated) - break; - mainForm->AnalyzeVirtualTable(1, vmtAdr, &Terminated); - } - } - StopProgress(); - // All procs - stepMask = StartProgress(CodeSize, msg); - for (int n = 0; n < CodeSize && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfProcStart, n)) { - DWORD adr = Pos2Adr(n); - UpdateAddrInStatusBar(adr); - mainForm->AnalyzeProc(1, adr); - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::AnalyzeCode2(bool args) { - PUnitRec recU; - - int stepMask = StartProgress(CodeSize, "Analyzing step 2..."); - - // EP - mainForm->AnalyzeProc(2, EP); - - for (int n = 0; n < CodeSize && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - if (IsFlagSet(cfProcStart, n)) { - DWORD adr = Pos2Adr(n); - UpdateAddrInStatusBar(adr); - if (args) - mainForm->AnalyzeArguments(adr); - mainForm->AnalyzeProc(2, adr); - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::PropagateClassProps() { - PInfoRec recN, recN1; - - int stepMask = StartProgress(CodeSize, "Propagating Class Properties..."); - for (int n = 0; n < CodeSize && !Terminated; n += 4) { - if ((n & stepMask) == 0) - UpdateProgress(); - recN = GetInfoRec(Pos2Adr(n)); - if (recN && recN->HasName()) { - BYTE typeKind = recN->kind; - if (typeKind > ikProcedure) - continue; - // Ïðîéäåìñÿ ïî ñâîéñòâàì êëàññà è ïîèìåíóåì ïðîöåäóðû - if (typeKind == ikClass) { - int pos = n; - // SelfPointer - pos += 4; - // TypeKind - pos++; - BYTE len = Code[pos]; - pos++; - String clsName = String((char*)(Code + pos), len); - pos += len; - DWORD classVMT = *((DWORD*)(Code + pos)); - pos += 4; - pos += 4; // ParentAdr - pos += 2; // PropCount - // UnitName - len = Code[pos]; - pos++; - pos += len; - WORD propCount = *((WORD*)(Code + pos)); - pos += 2; - - for (int i = 0; i < propCount && !Terminated; i++) { - DWORD propType = *((DWORD*)(Code + pos)); - pos += 4; - int posn = Adr2Pos(propType); - posn += 4; - posn++; // property type - len = Code[posn]; - posn++; - String typeName = String((char*)(Code + posn), len); - - DWORD getProc = *((DWORD*)(Code + pos)); - pos += 4; - DWORD setProc = *((DWORD*)(Code + pos)); - pos += 4; - DWORD storedProc = *((DWORD*)(Code + pos)); - pos += 4; - pos += 4; // Idx - pos += 4; // DefVal - pos += 2; // NameIdx - len = Code[pos]; - pos++; - String name = String((char*)(Code + pos), len); - pos += len; - - int vmtofs, fieldOfs; - PFIELDINFO fInfo; - - if ((getProc & 0xFFFFFF00)) { - if ((getProc & 0xFF000000) == 0xFF000000) { - fieldOfs = getProc & 0x00FFFFFF; - recN1 = GetInfoRec(classVMT + VmtSelfPtr); - if (recN1 && recN1->vmtInfo) - recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, name, typeName); - } - else if ((getProc & 0xFF000000) == 0xFE000000) { - if ((getProc & 0x00008000)) - vmtofs = -((int)getProc & 0x0000FFFF); - else - vmtofs = getProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - getProc = *((DWORD*)(Code + posn)); - recN1 = GetInfoRec(getProc); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(getProc), ikFunc); - else if (!recN1->procInfo) - recN1->procInfo = new InfoProcInfo; - - recN1->kind = ikFunc; - recN1->type = typeName; - if (!recN1->HasName()) - recN1->SetName(clsName + ".Get" + name); - recN1->procInfo->flags |= PF_METHOD; - recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - mainForm->AnalyzeProc1(getProc, 0, 0, 0, false); - } - else { - recN1 = GetInfoRec(getProc); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(getProc), ikFunc); - else if (!recN1->procInfo) - recN1->procInfo = new InfoProcInfo; - recN1->kind = ikFunc; - if (!recN1->HasName()) - recN1->SetName(clsName + ".Get" + name); - recN1->procInfo->flags |= PF_METHOD; - recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - mainForm->AnalyzeProc1(getProc, 0, 0, 0, false); - } - } - if ((setProc & 0xFFFFFF00)) { - if ((setProc & 0xFF000000) == 0xFF000000) { - fieldOfs = setProc & 0x00FFFFFF; - recN1 = GetInfoRec(classVMT + VmtSelfPtr); - if (recN1 && recN1->vmtInfo) - recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, name, typeName); - } - else if ((setProc & 0xFF000000) == 0xFE000000) { - if ((setProc & 0x00008000)) - vmtofs = -((int)setProc & 0x0000FFFF); - else - vmtofs = setProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - setProc = *((DWORD*)(Code + posn)); - recN1 = GetInfoRec(setProc); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(setProc), ikProc); - else if (!recN1->procInfo) - recN1->procInfo = new InfoProcInfo; - recN1->kind = ikProc; - if (!recN1->HasName()) - recN1->SetName(clsName + ".Set" + name); - recN1->procInfo->flags |= PF_METHOD; - recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); - mainForm->AnalyzeProc1(setProc, 0, 0, 0, false); - } - else { - recN1 = GetInfoRec(setProc); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(setProc), ikProc); - else if (!recN1->procInfo) - recN1->procInfo = new InfoProcInfo; - recN1->kind = ikProc; - if (!recN1->HasName()) - recN1->SetName(clsName + ".Set" + name); - recN1->procInfo->flags |= PF_METHOD; - recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); - mainForm->AnalyzeProc1(setProc, 0, 0, 0, false); - } - } - if ((storedProc & 0xFFFFFF00)) { - if ((storedProc & 0xFF000000) == 0xFF000000) { - fieldOfs = storedProc & 0x00FFFFFF; - recN1 = GetInfoRec(classVMT + VmtSelfPtr); - if (recN1 && recN1->vmtInfo) - recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, name, typeName); - } - else if ((storedProc & 0xFF000000) == 0xFE000000) { - if ((storedProc & 0x00008000)) - vmtofs = -((int)storedProc & 0x0000FFFF); - else - vmtofs = storedProc & 0x0000FFFF; - posn = Adr2Pos(classVMT) + vmtofs; - storedProc = *((DWORD*)(Code + posn)); - recN1 = GetInfoRec(storedProc); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(storedProc), ikFunc); - else if (!recN1->procInfo) - recN1->procInfo = new InfoProcInfo; - recN1->kind = ikFunc; - recN1->type = "Boolean"; - if (!recN1->HasName()) - recN1->SetName(clsName + ".IsStored" + name); - recN1->procInfo->flags |= PF_METHOD; - recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); - mainForm->AnalyzeProc1(storedProc, 0, 0, 0, false); - } - else { - recN1 = GetInfoRec(storedProc); - if (!recN1) - recN1 = new InfoRec(Adr2Pos(storedProc), ikFunc); - else if (!recN1->procInfo) - recN1->procInfo = new InfoProcInfo; - recN1->kind = ikFunc; - recN1->type = "Boolean"; - if (!recN1->HasName()) - recN1->SetName(clsName + ".IsStored" + name); - recN1->procInfo->flags |= PF_METHOD; - recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); - recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); - mainForm->AnalyzeProc1(storedProc, 0, 0, 0, false); - } - } - } - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::FillClassViewer() { - PVmtListRec recV; - - mainForm->tvClassesFull->Items->Clear(); - const int cntVmt = VmtList->Count; - if (!cntVmt) - return; - - int stepMask = StartProgress(cntVmt, "Building ClassViewer Tree..."); - TStringList *tmpList = new TStringList; - tmpList->Sorted = false; - - mainForm->tvClassesFull->Items->BeginUpdate(); - - for (int n = 0; n < cntVmt && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - - recV = (PVmtListRec)VmtList->Items[n]; - UpdateStatusBar(GetClsName(recV->vmtAdr)); - mainForm->FillClassViewerOne(n, tmpList, &Terminated); - } - - mainForm->tvClassesFull->Items->EndUpdate(); - - ProjectModified = true; - ClassTreeDone = true; - delete tmpList; - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::AnalyzeDC() { - int n, m, k, dotpos, pos, stepMask, instrLen; - DWORD vmtAdr, adr, procAdr, stopAt, classAdr; - String className, name; - PVmtListRec recV; - PInfoRec recN, recN1, recN2; - PARGINFO argInfo; - PMethodRec recM, recM1; - DISINFO disInfo; - - // Ñîçäàåì âðåìåííûé ñïèñîê ïàð (âûñîòà, àäðåñ VMT) - const int cntVmt = VmtList->Count; - if (!cntVmt) - return; - - stepMask = StartProgress(cntVmt, "Analyzing Constructors and Destructors, step 1..."); - for (n = 0; n < cntVmt && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - recV = (PVmtListRec)VmtList->Items[n]; - vmtAdr = recV->vmtAdr; - className = GetClsName(vmtAdr); - UpdateStatusBar(className); - - // Destructor - pos = Adr2Pos(vmtAdr) - VmtSelfPtr + VmtDestroy; - adr = *((DWORD*)(Code + pos)); - if (IsValidImageAdr(adr)) { - recN = GetInfoRec(adr); - if (recN && !recN->HasName()) { - recN->kind = ikDestructor; - recN->SetName(className + ".Destroy"); - } - } - // Constructor - recN = GetInfoRec(vmtAdr); - - if (recN && recN->xrefs) { - for (m = 0; m < recN->xrefs->Count; m++) { - PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; - adr = recX->adr + recX->offset; - recN1 = GetInfoRec(adr); - if (recN1 && !recN1->HasName()) { - if (IsFlagSet(cfProcStart, Adr2Pos(adr))) { - recN1->kind = ikConstructor; - recN1->SetName(className + ".Create"); - } - } - } - } - } - StopProgress(); - stepMask = StartProgress(cntVmt, "Analyzing Constructors, step 2..."); - for (n = 0; n < cntVmt && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - recV = (PVmtListRec)VmtList->Items[n]; - vmtAdr = recV->vmtAdr; - stopAt = GetStopAt(vmtAdr - VmtSelfPtr); - if (vmtAdr == stopAt) - continue; - - className = GetClsName(vmtAdr); - UpdateStatusBar(className); - pos = Adr2Pos(vmtAdr) - VmtSelfPtr + VmtParent + 4; - - for (m = VmtParent + 4; ; m += 4, pos += 4) { - if (Pos2Adr(pos) == stopAt) - break; - procAdr = *((DWORD*)(Code + pos)); - if (m >= 0) { - recN = GetInfoRec(procAdr); - if (recN && recN->kind == ikConstructor && !recN->HasName()) { - classAdr = vmtAdr; - while (classAdr) { - recM = mainForm->GetMethodInfo(classAdr, 'V', m); - if (recM) { - name = recM->name; - if (name != "") { - dotpos = name.Pos("."); - if (dotpos) - recN->SetName(className + name.SubString(dotpos, name.Length())); - else - recN->SetName(name); - break; - } - } - classAdr = GetParentAdr(classAdr); - } - } - } - } - } - StopProgress(); - stepMask = StartProgress(cntVmt, "Analyzing Dynamic Methods..."); - for (n = 0; n < cntVmt && !Terminated; n++) { - if ((n & stepMask) == 0) - UpdateProgress(); - recV = (PVmtListRec)VmtList->Items[n]; - vmtAdr = recV->vmtAdr; - className = GetClsName(vmtAdr); - UpdateStatusBar(className); - - recN = GetInfoRec(vmtAdr); - - if (recN && recN->vmtInfo->methods) { - for (m = 0; m < recN->vmtInfo->methods->Count; m++) { - recM = (PMethodRec)recN->vmtInfo->methods->Items[m]; - if (recM->kind == 'D') { - recN1 = GetInfoRec(recM->address); - if (recN1) { - classAdr = GetParentAdr(vmtAdr); - while (classAdr) { - recM1 = mainForm->GetMethodInfo(classAdr, 'D', recM->id); - if (recM1) { - recN2 = GetInfoRec(recM1->address); - if (recN2 && recN2->procInfo->args) { - for (k = 0; k < recN2->procInfo->args->Count; k++) { - if (!k) - recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); - else { - argInfo = (PARGINFO)recN2->procInfo->args->Items[k]; - recN1->procInfo->AddArg(argInfo); - } - } - } - } - classAdr = GetParentAdr(classAdr); - } - } - } - } - } - } - StopProgress(); -} - -// --------------------------------------------------------------------------- -void __fastcall TAnalyzeThread::ClearPassFlags() { - if (!Terminated) - mainForm->ClearPassFlags(); -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/Threads.h b/Sources/Libs/Threads.h deleted file mode 100644 index 912f7b3..0000000 --- a/Sources/Libs/Threads.h +++ /dev/null @@ -1,85 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef ThreadsH -#define ThreadsH -// --------------------------------------------------------------------------- -#include -#include "Main.h" -#include "ProgressBar.h" - -// --------------------------------------------------------------------------- -enum ThreadAnalysisOperation { - taStartPrBar, taUpdatePrBar, taUpdateStBar, taUpdateUnits, taUpdateRTTIs, taUpdateVmtList, taUpdateStrings, taUpdateCode, taUpdateXrefs, taUpdateShortClassViewer, taUpdateClassViewer, - taUpdateBeforeClassViewer, taFinished -}; - -struct ThreadAnalysisData { - ThreadAnalysisData(int steps, const String& txt) : pbSteps(steps), sbText(txt) { - } - - int pbSteps; - String sbText; -}; - -typedef struct { - int height; - DWORD vmtAdr; -} CVPair, *PCVPair; -// --------------------------------------------------------------------------- -#define LAST_ANALYZE_STEP 19 - -class TAnalyzeThread : public TThread { -private: - TFMain_11011981 *mainForm; - TFProgressBar *pbForm; - int adrCnt; - - int __fastcall StartProgress(int pbMaxCount, const String& sbText); - void __fastcall UpdateProgress(); - void __fastcall StopProgress(); - void __fastcall UpdateStatusBar(int adr); - void __fastcall UpdateStatusBar(const String& sbText); - void __fastcall UpdateAddrInStatusBar(DWORD adr); - void __fastcall UpdateUnits(); - void __fastcall UpdateRTTIs(); - void __fastcall UpdateVmtList(); - void __fastcall UpdateStrings(); - void __fastcall UpdateCode(); - void __fastcall UpdateXrefs(); - void __fastcall UpdateShortClassViewer(); - void __fastcall UpdateClassViewer(); - void __fastcall UpdateBeforeClassViewer(); - void __fastcall StrapSysProcs(); - void __fastcall FindRTTIs(); - void __fastcall FindVMTs2(); // Äëÿ âåðñèè Äåëüôè2 (äðóãàÿ ñòðóêòóðà!) - void __fastcall FindVMTs(); - void __fastcall FindTypeFields(); - String __fastcall FindEvent(DWORD VmtAdr, String Name); - void __fastcall FindPrototypes(); - void __fastcall StrapVMTs(); - void __fastcall ScanCode(); - void __fastcall ScanCode1(); - void __fastcall ScanVMTs(); - void __fastcall ScanConsts(); - void __fastcall ScanGetSetStoredProcs(); - void __fastcall FindStrings(); - void __fastcall AnalyzeCode1(); - void __fastcall AnalyzeCode2(bool args); - void __fastcall AnalyzeCode3(); - void __fastcall PropagateClassProps(); - void __fastcall FillClassViewer(); - void __fastcall AnalyzeDC(); - - void __fastcall ClearPassFlags(); - -protected: - void __fastcall Execute(); - -public: - __fastcall TAnalyzeThread(TFMain_11011981* AForm, TFProgressBar* ApbForm, bool AllValues); - __fastcall ~TAnalyzeThread(); - int __fastcall GetRetVal(); - - bool all; // if false, only ClassViewer -}; -// --------------------------------------------------------------------------- -#endif diff --git a/Sources/Libs/UFileDropper.cpp b/Sources/Libs/UFileDropper.cpp deleted file mode 100644 index 263568e..0000000 --- a/Sources/Libs/UFileDropper.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// --------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "UFileDropper.h" -// --------------------------------------------------------------------------- -#pragma package(smart_init) - -// --------------------------------------------------------------------------- -TDragDropHelper::TDragDropHelper(const HWND h) : wndHandle(h) { - ::DragAcceptFiles(wndHandle, true); -} - -// --------------------------------------------------------------------------- -TDragDropHelper::~TDragDropHelper() { - ::DragAcceptFiles(wndHandle, false); -} - -// --------------------------------------------------------------------------- -__fastcall TFileDropper::TFileDropper(HDROP aDropHandle) : DropHandle(aDropHandle) { -} - -// --------------------------------------------------------------------------- -__fastcall TFileDropper::~TFileDropper() { - ::DragFinish(DropHandle); -} - -// --------------------------------------------------------------------------- -String TFileDropper::GetFile(int Index) { - const int FileNameLength = ::DragQueryFile(DropHandle, Index, 0, 0); - - String res; - res.SetLength(FileNameLength); - ::DragQueryFile(DropHandle, Index, AnsiString(res).c_str(), FileNameLength + 1); - - return res; -} - -// --------------------------------------------------------------------------- -int TFileDropper::GetFileCount() { - return ::DragQueryFile(DropHandle, 0xFFFFFFFF, 0, 0); -} - -// --------------------------------------------------------------------------- -TPoint TFileDropper::GetPoint() { - TPoint res(0, 0); - DragQueryPoint(DropHandle, &res); - return res; -} -// --------------------------------------------------------------------------- diff --git a/Sources/Libs/UFileDropper.h b/Sources/Libs/UFileDropper.h deleted file mode 100644 index 3f2ac4f..0000000 --- a/Sources/Libs/UFileDropper.h +++ /dev/null @@ -1,40 +0,0 @@ -// --------------------------------------------------------------------------- -#ifndef UFileDropperH -#define UFileDropperH - -// #include - -// -// simple class that allow/disallow drag-drop support for window -// -class TDragDropHelper { -public: - TDragDropHelper(const HWND); - ~TDragDropHelper(); - -private: - const HWND wndHandle; -}; - -// -// simple class that accepts dropped files and stores names + droppoint -// -class TFileDropper : public TObject { -public: - __fastcall TFileDropper(HDROP); - virtual __fastcall ~TFileDropper(); - - __property int FileCount = {read = GetFileCount}; - __property String Files[int Index] = {read = GetFile}; - __property TPoint DropPoint = {read = GetPoint}; - -private: - HDROP DropHandle; - - String GetFile(int Index); - int GetFileCount(); - TPoint GetPoint(); -}; - -// --------------------------------------------------------------------------- -#endif diff --git a/StringInfo.cpp b/StringInfo.cpp new file mode 100644 index 0000000..5499c19 --- /dev/null +++ b/StringInfo.cpp @@ -0,0 +1,29 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "StringInfo.h" +#include "Misc.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "TntStdCtrls" +#pragma resource "*.dfm" +TFStringInfo_11011981 *FStringInfo_11011981; +//--------------------------------------------------------------------------- +__fastcall TFStringInfo_11011981::TFStringInfo_11011981(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TFStringInfo_11011981::FormKeyDown(TObject *Sender, + WORD &Key, TShiftState Shift) +{ + if (Key == VK_ESCAPE) ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFStringInfo_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/StringInfo.dfm b/StringInfo.dfm similarity index 66% rename from Sources/Forms/StringInfo.dfm rename to StringInfo.dfm index 3d6b60c..b69cd63 100644 --- a/Sources/Forms/StringInfo.dfm +++ b/StringInfo.dfm @@ -1,12 +1,12 @@ object FStringInfo_11011981: TFStringInfo_11011981 Left = 270 Top = 390 - ClientHeight = 151 - ClientWidth = 837 + Width = 853 + Height = 190 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText - Font.Height = -13 + Font.Height = -10 Font.Name = 'MS Sans Serif' Font.Style = [] KeyPreview = True @@ -14,24 +14,22 @@ object FStringInfo_11011981: TFStringInfo_11011981 Position = poScreenCenter OnCreate = FormCreate OnKeyDown = FormKeyDown - PixelsPerInch = 120 - TextHeight = 16 - object memStringInfo: TMemo + PixelsPerInch = 96 + TextHeight = 13 + object memStringInfo: TTntMemo Left = 0 Top = 0 Width = 837 - Height = 151 + Height = 152 Align = alClient - Font.Charset = DEFAULT_CHARSET + Font.Charset = ANSI_CHARSET Font.Color = clWindowText - Font.Height = -15 + Font.Height = -12 Font.Name = 'Fixedsys' Font.Style = [] ParentFont = False ReadOnly = True ScrollBars = ssVertical TabOrder = 0 - ExplicitWidth = 845 - ExplicitHeight = 150 end end diff --git a/StringInfo.h b/StringInfo.h new file mode 100644 index 0000000..0692021 --- /dev/null +++ b/StringInfo.h @@ -0,0 +1,25 @@ +//--------------------------------------------------------------------------- +#ifndef StringInfoH +#define StringInfoH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include "TntStdCtrls.hpp" +//--------------------------------------------------------------------------- +class TFStringInfo_11011981 : public TForm +{ +__published: // IDE-managed Components + TTntMemo *memStringInfo; + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall FormCreate(TObject *Sender); +private: // User declarations +public: // User declarations + __fastcall TFStringInfo_11011981(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFStringInfo_11011981 *FStringInfo_11011981; +//--------------------------------------------------------------------------- +#endif diff --git a/TabNames.cpp b/TabNames.cpp new file mode 100644 index 0000000..3794a90 --- /dev/null +++ b/TabNames.cpp @@ -0,0 +1,84 @@ +void __fastcall TFMain_11011981::ShowNames(int idx) +{ + int n, wid, maxwid = 0; + PInfoRec recN; + String line; + TCanvas* canvas = lbNames->Canvas; + + lbNames->Clear(); + lbNames->Items->BeginUpdate(); + + for (n = CodeSize; n < TotalSize; n++) + { + if (IsFlagSet(cfImport, n)) continue; + recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->HasName()) + { + line = Val2Str8(Pos2Adr(n)) + " " + recN->GetName(); + if (recN->type != "") line += ":" + recN->type; + lbNames->Items->Add(line); + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + } + } + for (n = 0; n < BSSInfos->Count; n++) + { + recN = (PInfoRec)BSSInfos->Objects[n]; + line = BSSInfos->Strings[n] + " " + recN->GetName(); + if (recN->type != "") line += ":" + recN->type; + lbNames->Items->Add(line); + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + } + lbNames->Items->EndUpdate(); + + lbNames->ItemIndex = idx; + lbNames->ScrollWidth = maxwid + 2; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowNameXrefs(DWORD Adr, int selIdx) +{ + PInfoRec recN; + + lbNXrefs->Clear(); + + recN = GetInfoRec(Adr); + if (recN && recN->xrefs) + { + int wid, maxwid = 0; + TCanvas *canvas = lbNXrefs->Canvas; + DWORD pAdr = 0; + char f = 2; + + lbNXrefs->Items->BeginUpdate(); + for (int m = 0; m < recN->xrefs->Count; m++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; + String line = " " + Val2Str8(recX->adr + recX->offset) + " " + recX->type; + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + PUnitRec recU = GetUnit(recX->adr); + if (recU && recU->kb) line[1] ^= 1; + if (pAdr != recX->adr) f ^= 2; line[1] ^= f; + pAdr = recX->adr; + lbNXrefs->Items->Add(line); + } + lbNXrefs->Items->EndUpdate(); + + lbNXrefs->ScrollWidth = maxwid + 2; + lbNXrefs->ItemIndex = selIdx; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbNamesClick(TObject *Sender) +{ + //NamesSearchFrom = lbNames->ItemIndex; + //WhereSearch = SEARCH_NAMES; + + if (lbNames->ItemIndex >= 0) + { + DWORD adr; + String line = lbNames->Items->Strings[lbNames->ItemIndex]; + sscanf(line.c_str() + 1, "%lX", &adr); + ShowNameXrefs(adr, -1); + } +} +//--------------------------------------------------------------------------- + diff --git a/TabRTTIs.cpp b/TabRTTIs.cpp new file mode 100644 index 0000000..a8c393c --- /dev/null +++ b/TabRTTIs.cpp @@ -0,0 +1,154 @@ +//--------------------------------------------------------------------------- +int __fastcall SortRTTIsByAdr(void *item1, void *item2) +{ + PTypeRec rec1 = (PTypeRec)item1; + PTypeRec rec2 = (PTypeRec)item2; + if (rec1->adr > rec2->adr) return 1; + if (rec1->adr < rec2->adr) return -1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall SortRTTIsByKnd(void *item1, void *item2) +{ + PTypeRec rec1 = (PTypeRec)item1; + PTypeRec rec2 = (PTypeRec)item2; + if (rec1->kind > rec2->kind) return 1; + if (rec1->kind < rec2->kind) return -1; + return CompareText(rec1->name, rec2->name); +} +//--------------------------------------------------------------------------- +int __fastcall SortRTTIsByNam(void *item1, void *item2) +{ + PTypeRec rec1 = (PTypeRec)item1; + PTypeRec rec2 = (PTypeRec)item2; + return CompareText(rec1->name, rec2->name); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowRTTIs() +{ + lbRTTIs->Clear(); + //as + lbRTTIs->Items->BeginUpdate(); + + if (OwnTypeList->Count) + { + switch (RTTISortField) + { + case 0: + OwnTypeList->Sort(SortRTTIsByAdr); + break; + case 1: + OwnTypeList->Sort(SortRTTIsByKnd); + break; + case 2: + OwnTypeList->Sort(SortRTTIsByNam); + break; + } + } + + int wid, maxwid = 0; + TCanvas *canvas = lbUnits->Canvas; + String line; + for (int n = 0; n < OwnTypeList->Count; n++) + { + PTypeRec recT = (PTypeRec)OwnTypeList->Items[n]; + if (recT->kind == ikVMT) + line = Val2Str8(recT->adr) + " " + recT->name; + else + line = Val2Str8(recT->adr) + " <" + TypeKind2Name(recT->kind) + "> " + recT->name; + lbRTTIs->Items->Add(line); + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + } + lbRTTIs->Items->EndUpdate(); + + lbRTTIs->ScrollWidth = maxwid + 2; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbRTTIsDblClick(TObject *Sender) +{ + DWORD adr; + char tkName[32], typeName[1024]; + + sscanf(lbRTTIs->Items->Strings[lbRTTIs->ItemIndex].c_str(), "%lX%s%s", &adr, tkName, typeName); + String name = String(tkName); + + if (SameText(name, "") && tsClassView->TabVisible) + { + ShowClassViewer(adr); + return; + } + + FTypeInfo_11011981->ShowRTTI(adr); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbRTTIsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if (lbRTTIs->CanFocus()) ActiveControl = lbRTTIs; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbRTTIsClick(TObject *Sender) +{ + RTTIsSearchFrom = lbRTTIs->ItemIndex; + WhereSearch = SEARCH_RTTIS; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbRTTIsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + if (Key == VK_RETURN) lbRTTIsDblClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchRTTIClick(TObject *Sender) +{ + WhereSearch = SEARCH_RTTIS; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < RTTIsSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(RTTIsSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (lbRTTIs->ItemIndex < 0) + RTTIsSearchFrom = 0; + else + RTTIsSearchFrom = lbRTTIs->ItemIndex; + + RTTIsSearchText = FindDlg_11011981->cbText->Text; + if (RTTIsSearchList->IndexOf(RTTIsSearchText) == -1) RTTIsSearchList->Add(RTTIsSearchText); + FindText(RTTIsSearchText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmRTTIsPopup(TObject *Sender) +{ + if (lbRTTIs->ItemIndex < 0) return; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSortRTTIsByAdrClick(TObject *Sender) +{ + miSortRTTIsByAdr->Checked = true; + miSortRTTIsByKnd->Checked = false; + miSortRTTIsByNam->Checked = false; + RTTISortField = 0; + ShowRTTIs(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSortRTTIsByKndClick(TObject *Sender) +{ + miSortRTTIsByAdr->Checked = false; + miSortRTTIsByKnd->Checked = true; + miSortRTTIsByNam->Checked = false; + RTTISortField = 1; + ShowRTTIs(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSortRTTIsByNamClick(TObject *Sender) +{ + miSortRTTIsByAdr->Checked = false; + miSortRTTIsByKnd->Checked = false; + miSortRTTIsByNam->Checked = true; + RTTISortField = 2; + ShowRTTIs(); +} +//--------------------------------------------------------------------------- diff --git a/TabStrings.cpp b/TabStrings.cpp new file mode 100644 index 0000000..d83c6ae --- /dev/null +++ b/TabStrings.cpp @@ -0,0 +1,249 @@ +extern WideString __fastcall UnicodeEncode(String Str, int CodePage); +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowStrings(int idx) +{ + int n, itemidx, wid, maxwid = 0; + PInfoRec recN; + String line, line1, str; + TCanvas* canvas = lbStrings->Canvas; + + lbStrings->Clear(); + lbStrings->Items->BeginUpdate(); + + for (n = 0; n < CodeSize; n++) + { + recN = GetInfoRec(Pos2Adr(n)); + if (recN && !IsFlagSet(cfRTTI, n)) + { + if (recN->kind == ikResString && recN->rsInfo->value != "") + { + //line = " " + Val2Str8(Pos2Adr(n)) + " " + recN->rsInfo->value; + line = Val2Str8(Pos2Adr(n)) + " " + recN->rsInfo->value; + if (recN->rsInfo->value.Length() <= MAXLEN) + line1 = line; + else + { + line1 = line.SubString(1, MAXLEN) + "..."; //line1[1] ^= 1; + } + lbStrings->Items->Add(line1); + wid = canvas->TextWidth(line1); if (wid > maxwid) maxwid = wid; + continue; + } + if (recN->HasName()) + { + switch (recN->kind) + { + case ikString: + str = ""; + break; + case ikLString: + str = ""; + break; + case ikWString: + str = ""; + break; + case ikCString: + str = ""; + break; + case ikWCString: + str = ""; + break; + case ikUString: + str = ""; + break; + default: + str = ""; + break; + } + if (str != "") + { + //bool truncate = false; + //line = " " + Val2Str8(Pos2Adr(n)) + " " + str + " " + recN->GetName(); + line = Val2Str8(Pos2Adr(n)) + " " + str + " " + recN->GetName(); + if (recN->GetNameLength() <= MAXLEN) + line1 = line; + else + { + line1 = line.SubString(1, MAXLEN) + "..."; + //truncate = true; + } + WideString ws = UnicodeEncode(line1, CodePage); + //if (truncate) line1[1] ^= 1; + lbStrings->Items->Add(ws); + wid = canvas->TextWidth(line1); if (wid > maxwid) maxwid = wid; + } + } + } + } + lbStrings->ItemIndex = idx; + lbStrings->ScrollWidth = maxwid + 2; + lbStrings->ItemHeight = lbStrings->Canvas->TextHeight("T"); + lbStrings->Items->EndUpdate(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbStringsClick(TObject *Sender) +{ + StringsSearchFrom = lbStrings->ItemIndex; + WhereSearch = SEARCH_STRINGS; + + if (lbStrings->ItemIndex >= 0) + { + DWORD adr; + String line = lbStrings->Items->Strings[lbStrings->ItemIndex]; + //sscanf(line.c_str() + 1, "%lX", &adr); + sscanf(line.c_str(), "%lX", &adr); + ShowStringXrefs(adr, -1); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbStringsDblClick(TObject *Sender) +{ + DWORD adr; + String line = lbStrings->Items->Strings[lbStrings->ItemIndex]; + //sscanf(line.c_str() + 1, "%lX", &adr); + sscanf(line.c_str(), "%lX", &adr); + if (IsValidImageAdr(adr)) + { + PInfoRec recN = GetInfoRec(adr); + + if (recN->kind == ikResString) + { + FStringInfo_11011981->Caption = "ResString context"; + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); + FStringInfo_11011981->ShowModal(); + } + else + { + FStringInfo_11011981->Caption = "String context"; + FStringInfo_11011981->memStringInfo->Clear(); + WideString ws = UnicodeEncode(recN->GetName(), CodePage); + FStringInfo_11011981->memStringInfo->Lines->Add(UnicodeEncode(recN->GetName(), CodePage)); + FStringInfo_11011981->ShowModal(); + } + } +} +//--------------------------------------------------------------------------- +/* +void __fastcall TFMain_11011981::lbStringsDrawItem(TWinControl *Control, + int Index, TRect &Rect, TOwnerDrawState State) +{ + int flags; + TColor _color; + TListBox *lb; + TCanvas *canvas; + String text, str; + + lb = (TListBox*)Control; + canvas = lb->Canvas; + SaveCanvas(canvas); + + if (Index < lb->Count) + { + flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); + if (!Control->UseRightToLeftAlignment()) + Rect.Left += 2; + else + Rect.Right -= 2; + canvas->FillRect(Rect); + + text = lb->Items->Strings[Index]; + //lb->ItemHeight = canvas->TextHeight(text); + str = text.SubString(2, text.Length() - 1); + + //Long strings + if (text[1] & 1) + _color = TColor(0xBBBBBB); //LightGray + else + _color = TColor(0);//Black + + Rect.Right = Rect.Left; + DrawOneItem(str, canvas, Rect, _color, flags); + } + RestoreCanvas(canvas); +} +*/ +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchStringClick(TObject *Sender) +{ + WhereSearch = SEARCH_STRINGS; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < StringsSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(StringsSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (lbStrings->ItemIndex < 0) + StringsSearchFrom = 0; + else + StringsSearchFrom = lbStrings->ItemIndex; + + StringsSearchText = FindDlg_11011981->cbText->Text; + if (StringsSearchList->IndexOf(StringsSearchText) == -1) StringsSearchList->Add(StringsSearchText); + FindText(StringsSearchText); + + DWORD adr; + String line = lbStrings->Items->Strings[lbStrings->ItemIndex]; + //sscanf(line.c_str() + 1, "%lX", &adr); + sscanf(line.c_str(), "%lX", &adr); + ShowStringXrefs(adr, -1); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbStringsMouseMove( + TObject *Sender, TShiftState Shift, int X, int Y) +{ + if (lbStrings->CanFocus()) ActiveControl = lbStrings; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowSXrefsClick(TObject *Sender) +{ + if (lbSXrefs->Visible) + { + ShowSXrefs->BevelOuter = bvRaised; + lbSXrefs->Visible = false; + } + else + { + ShowSXrefs->BevelOuter = bvLowered; + lbSXrefs->Visible = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowStringXrefs(DWORD Adr, int selIdx) +{ + lbSXrefs->Clear(); + + PInfoRec recN = GetInfoRec(Adr); + if (recN && recN->xrefs) + { + int wid, maxwid = 0; + TCanvas *canvas = lbSXrefs->Canvas; + DWORD pAdr = 0; + char f = 2; + + lbSXrefs->Items->BeginUpdate(); + for (int m = 0; m < recN->xrefs->Count; m++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; + String line = " " + Val2Str8(recX->adr + recX->offset) + " " + recX->type; + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + PUnitRec recU = GetUnit(recX->adr); + if (recU && recU->kb) line[1] ^= 1; + if (pAdr != recX->adr) f ^= 2; line[1] ^= f; + pAdr = recX->adr; + lbSXrefs->Items->Add(line); + } + lbSXrefs->Items->EndUpdate(); + + lbSXrefs->ScrollWidth = maxwid + 2; + lbSXrefs->ItemIndex = selIdx; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::pmStringsPopup(TObject *Sender) +{ + if (lbStrings->ItemIndex < 0) return; +} +//--------------------------------------------------------------------------- diff --git a/TabUnits.cpp b/TabUnits.cpp new file mode 100644 index 0000000..9290771 --- /dev/null +++ b/TabUnits.cpp @@ -0,0 +1,990 @@ + +extern WideString __fastcall UnicodeEncode(String Str, int CodePage); +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSortUnitsByAdrClick(TObject *Sender) +{ + miSortUnitsByAdr->Checked = true; + miSortUnitsByOrd->Checked = false; + miSortUnitsByNam->Checked = false; + UnitSortField = 0; + ShowUnits(true); + lbUnits->SetFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSortUnitsByOrdClick(TObject *Sender) +{ + miSortUnitsByAdr->Checked = false; + miSortUnitsByOrd->Checked = true; + miSortUnitsByNam->Checked = false; + UnitSortField = 1; + ShowUnits(true); + lbUnits->SetFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSortUnitsByNamClick(TObject *Sender) +{ + miSortUnitsByAdr->Checked = false; + miSortUnitsByOrd->Checked = false; + miSortUnitsByNam->Checked = true; + UnitSortField = 2; + ShowUnits(true); + lbUnits->SetFocus(); +} +//--------------------------------------------------------------------------- +bool __fastcall TFMain_11011981::ContainsUnexplored(PUnitRec recU) +{ + if (!recU) return false; + + bool unk = false; + for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + int n = Adr2Pos(adr); + if (!Flags[n]) + { + BYTE b0 = *(Code + n); + if (!unk) + { + BYTE b1 = *(Code + n + 1); BYTE b2 = *(Code + n + 2); + if ((adr & 3) == 3 && (b0 == 0 || b0 == 0x90)) + continue; + if ((adr & 3) == 2 && ((b0 == 0 && b1 == 0) || (b0 == 0x8B && b1 == 0xC0))) + { + adr++; + continue; + } + if ((adr & 3) == 1 && ((b0 == 0 && b1 == 0 && b2 == 0) || (b0 == 0x8D && b1 == 0x40 && b2 == 0))) + { + adr += 2; + continue; + } + unk = true; + } + continue; + } + + if (unk) return true; + } + return false; +} +//--------------------------------------------------------------------------- +#define TRIV_UNIT 1 //Trivial unit +#define USER_UNIT 2 //User unit +#define UNEXP_UNIT 4 //Unit has undefined bytes +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowUnits(bool showUnk) +{ + int oldItemIdx = lbUnits->ItemIndex; + DWORD selAdr = 0; + if (oldItemIdx != -1) + { + String item = lbUnits->Items->Strings[oldItemIdx]; + sscanf(item.c_str() + 1, "%lX", &selAdr); + } + int oldTopIdx = lbUnits->TopIndex; + + lbUnits->Clear(); + lbUnits->Items->BeginUpdate(); + + if (UnitsNum) + { + switch (UnitSortField) + { + case 0: + Units->Sort(SortUnitsByAdr); + break; + case 1: + Units->Sort(SortUnitsByOrd); + break; + case 2: + Units->Sort(SortUnitsByNam); + break; + } + } + + int stringLen; + int newItemIdx = -1; + int wid, maxwid = 0; + TCanvas *canvas = lbUnits->Canvas; + char ci, cf, orderS[256]; + + for (int i = 0; i < UnitsNum; i++) + { + PUnitRec recU = (UnitRec*)Units->Items[i]; + if (recU->fromAdr == selAdr) newItemIdx = i; + ci = (!recU->trivialIni) ? 'I' : ' '; + cf = (!recU->trivialFin) ? 'F' : ' '; + stringLen = sprintf(StringBuf, " %08lX #%03d %c%c ", (int)recU->fromAdr, recU->iniOrder, ci, cf); + if (recU->names->Count) + { + for (int u = 0; u < recU->names->Count; u++) + { + if (stringLen + recU->names->Strings[u].Length() >= 256) + { + stringLen += sprintf(StringBuf + stringLen, "..."); + break; + } + if (u) + { + StringBuf[stringLen] = ';'; + stringLen++; + } + stringLen += sprintf(StringBuf + stringLen, "%s", recU->names->Strings[u].c_str()); + } + } + else + stringLen += sprintf(StringBuf + stringLen, "_Unit%d", recU->iniOrder); + + if (i != UnitsNum - 1) + { + //Trivial units + if (recU->trivial) + StringBuf[0] = TRIV_UNIT; + else if (!recU->kb) + StringBuf[0] = USER_UNIT; + } + //Last unit is user's + else + StringBuf[0] = USER_UNIT; + + //Unit has undefined bytes + if (showUnk && ContainsUnexplored(recU)) StringBuf[0] |= UNEXP_UNIT; + String line = String(StringBuf, stringLen); + lbUnits->Items->Add(line); + wid = canvas->TextWidth(line); if (wid > maxwid) maxwid = wid; + } + if (newItemIdx == -1) + lbUnits->TopIndex = oldTopIdx; + else + { + if (newItemIdx != oldItemIdx) + { + lbUnits->ItemIndex = newItemIdx; + int newTopIdx = newItemIdx - (oldItemIdx - oldTopIdx); + if (newTopIdx < 0) newTopIdx = 0; + lbUnits->TopIndex = newTopIdx; + } + else + { + lbUnits->ItemIndex = newItemIdx; + lbUnits->TopIndex = oldTopIdx; + } + } + lbUnits->ItemHeight = lbUnits->Canvas->TextHeight("T"); + lbUnits->ScrollWidth = maxwid + 2; + lbUnits->Items->EndUpdate(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitsMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if (lbUnits->CanFocus()) ActiveControl = lbUnits; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitsClick(TObject *Sender) +{ + UnitsSearchFrom = lbUnits->ItemIndex; + WhereSearch = SEARCH_UNITS; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitsDblClick(TObject *Sender) +{ + DWORD adr; + + String item = lbUnits->Items->Strings[lbUnits->ItemIndex]; + sscanf(item.c_str() + 1, "%lX", &adr); + PUnitRec recU = GetUnit(adr); + + if (!CurUnitAdr || adr != CurUnitAdr) + { + CurUnitAdr = adr; + ShowUnitItems(recU, 0, -1); + } + else + { + ShowUnitItems(recU, lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + } + + CurUnitAdr = adr; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitsKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + if (Key == VK_RETURN) lbUnitsDblClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitsDrawItem( + TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) +{ + char *s, *pos; + int flags, len; + TColor _color; + TListBox *lb; + TCanvas *canvas; + String text, str1, str2; + + lb = (TListBox*)Control; + canvas = lb->Canvas; + SaveCanvas(canvas); + + if (Index < lb->Count) + { + flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); + if (!Control->UseRightToLeftAlignment()) + Rect.Left += 2; + else + Rect.Right -= 2; + + text = lb->Items->Strings[Index]; + //lb->ItemHeight = canvas->TextHeight(text); + canvas->FillRect(Rect); + + s = text.c_str(); + //*XXXXXXXX #XXX XX NAME + pos = strrchr(s, ' '); + len = pos - s; + str1 = text.SubString(2, len - 1); + str2 = text.SubString(len + 1, text.Length() - len); + + if (!State.Contains(odSelected)) + _color = TColor(0); //Black + else + _color = TColor(0xBBBBBB); //LightGray + Rect.Right = Rect.Left; + DrawOneItem(str1, canvas, Rect, _color, flags); + + //Unit name + //Trivial unit - red + if (text[1] & TRIV_UNIT) + { + if (!State.Contains(odSelected)) + _color = TColor(0x0000B0); //Red + else + _color = TColor(0xBBBBBB); //LightGray + } + else + { + //User unit - green + if (text[1] & USER_UNIT) + { + if (!State.Contains(odSelected)) + { + if (text[1] & UNEXP_UNIT) + _color = TColor(0xC0C0FF); //Light Red + else + _color = TColor(0x00B000); //Green + } + else + _color = TColor(0xBBBBBB); //LightGray + } + //From knowledge base - blue + else + { + if (!State.Contains(odSelected)) + _color = TColor(0xC08000); //Blue + else + _color = TColor(0xBBBBBB); //LightGray + } + } + DrawOneItem(str2, canvas, Rect, _color, flags); + } + RestoreCanvas(canvas); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchUnitClick(TObject *Sender) +{ + WhereSearch = SEARCH_UNITS; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < UnitsSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(UnitsSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (lbUnits->ItemIndex == -1) + UnitsSearchFrom = 0; + else + UnitsSearchFrom = lbUnits->ItemIndex; + + UnitsSearchText = FindDlg_11011981->cbText->Text; + if (UnitsSearchList->IndexOf(UnitsSearchText) == -1) UnitsSearchList->Add(UnitsSearchText); + FindText(UnitsSearchText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miRenameUnitClick(TObject *Sender) +{ + if (lbUnits->ItemIndex == -1) return; + + String item = lbUnits->Items->Strings[lbUnits->ItemIndex]; + DWORD adr; + sscanf(item.c_str() + 1, "%lX", &adr); + PUnitRec recU = GetUnit(adr); + + String text = ""; + for (int u = 0; u < recU->names->Count; u++) + { + if (u) text += "+"; + text += recU->names->Strings[u]; + } + String sName = InputDialogExec("Enter UnitName", "Name:", text); + if (sName != "") + { + recU->names->Clear(); + SetUnitName(recU, sName); + + ProjectModified = true; + ShowUnits(true); + RedrawCode(); + lbUnits->SetFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::ShowUnitItems(PUnitRec recU, int topIdx, int itemIdx) +{ + bool unk = false; + bool imp, exp, emb, xref; + int wid, maxwid = 0; + TCanvas *canvas = lbUnitItems->Canvas; + String line, prefix; + + if (!CurUnitAdr) return; + + //if (AnalyzeThread) AnalyzeThread->Suspend(); + + lbUnitItems->Clear(); + lbUnitItems->Items->BeginUpdate(); + + for (DWORD adr = recU->fromAdr; adr < recU->toAdr; adr++) + { + int unknum, pos = Adr2Pos(adr); + if (!IsFlagSet(~cfLoc, pos)) + { + BYTE b0 = *(Code + pos); + if (!unk) + { + unknum = 0; + BYTE b1 = *(Code + pos + 1); BYTE b2 = *(Code + pos + 2); + if ((adr & 3) == 3 && (b0 == 0 || b0 == 0x90)) + continue; + if ((adr & 3) == 2 && ((b0 == 0 && b1 == 0) || (b0 == 0x8B && b1 == 0xC0) || (b0 == 0x90 && b1 == 0x90))) + { + adr++; + continue; + } + if ((adr & 3) == 1 && ((b0 == 0 && b1 == 0 && b2 == 0) || (b0 == 0x8D && b1 == 0x40 && b2 == 0) || (b0 == 0x90 && b1 == 0x90 && b2 == 0x90))) + { + adr += 2; + continue; + } + line = " " + Val2Str8(adr) + " ????"; line[1] ^= 1; + line += " " + Val2Str2(b0); unknum++; + unk = true; + } + else + { + if (unknum <= 16) + { + if (unknum == 16) + line += "..."; + else + line += " " + Val2Str2(b0); + unknum++; + } + } + continue; + } + + if (unk) + { + lbUnitItems->Items->Add(line); + wid = canvas->TextWidth(line); + if (wid > maxwid) maxwid = wid; + unk = false; + } + + if (adr == recU->iniadr) continue; + if (adr == recU->finadr) continue; + + //EP + if (adr == EP) + { + line = " " + Val2Str8(adr) + " EntryPoint"; + lbUnitItems->Items->Add(line); + wid = canvas->TextWidth(line); + if (wid > maxwid) maxwid = wid; + continue; + } + + PInfoRec recN = GetInfoRec(adr); + if (!recN) continue; + + BYTE kind = recN->kind; + //Skip calls, that are in the body of some asm-procs (for example, FloatToText from SysUtils) + //if (kind >= ikRefine && kind <= ikFunc && recN->procInfo && IsFlagSet(cfImport, pos)) continue; + + imp = IsFlagSet(cfImport, pos); + exp = IsFlagSet(cfExport, pos); + emb = false; + if (IsFlagSet(cfProcStart, pos)) + { + if (recN->procInfo) + { + emb = (recN->procInfo->flags & PF_EMBED); + } + } + xref = false; + + line = ""; + + switch (kind) + { + case ikInteger: + case ikChar: + case ikEnumeration: + case ikFloat: + case ikSet: + case ikClass: + case ikMethod: + case ikWChar: + case ikLString: + case ikVariant: + case ikArray: + case ikRecord: + case ikInterface: + case ikInt64: + case ikDynArray: + case ikUString: + case ikClassRef: + case ikPointer: + case ikProcedure: + line = "<" + TypeKind2Name(kind) + "> "; + if (recN->HasName()) + { + if (recN->GetNameLength() <= MAXLEN) + line += recN->GetName(); + else + { + line += recN->GetName().SubString(1, MAXLEN) + "..."; + } + } + break; + case ikString: + if (!IsFlagSet(cfRTTI, pos)) + line = " "; + else + line = "<" + TypeKind2Name(kind) + "> "; + if (recN->HasName()) + { + if (recN->GetNameLength() <= MAXLEN) + line += recN->GetName(); + else + { + line += recN->GetName().SubString(1, MAXLEN) + "..."; + } + } + break; + case ikWString: + line = " "; + if (recN->HasName()) + { + if (recN->GetNameLength() <= MAXLEN) + line += recN->GetName(); + else + { + line += recN->GetName().SubString(1, MAXLEN) + "..."; + } + } + break; + case ikCString: + line = " "; + if (recN->HasName()) + { + if (recN->GetNameLength() <= MAXLEN) + line += recN->GetName(); + else + { + line += recN->GetName().SubString(1, MAXLEN) + "..."; + } + } + break; + case ikWCString: + line = " "; + if (recN->HasName()) + { + if (recN->GetNameLength() <= MAXLEN) + line += recN->GetName(); + else + { + line += recN->GetName().SubString(1, MAXLEN) + "..."; + } + } + break; + case ikResString: + if (recN->HasName()) line += " " + recN->GetName() + "=" + recN->rsInfo->value; + break; + case ikVMT: + line = " "; + if (recN->HasName()) line += recN->GetName(); + break; + case ikConstructor: + xref = true; + line = " " + recN->MakePrototype(adr, false, true, false, true, false); + break; + case ikDestructor: + xref = true; + line = " " + recN->MakePrototype(adr, false, true, false, true, false); + break; + case ikProc: + xref = true; + line = "<"; + if (imp) + line += "Imp"; + else if (exp) + line += "Exp"; + else if (emb) + line += "Emb"; + line += "Proc> " + recN->MakePrototype(adr, false, true, false, true, false); + break; + case ikFunc: + xref = true; + line = "<"; + if (imp) + line += "Imp"; + else if (exp) + line += "Exp"; + else if (emb) + line += "Emb"; + line += "Func> " + recN->MakePrototype(adr, false, true, false, true, false); + break; + case ikGUID: + line = " "; + if (recN->HasName()) line += recN->GetName(); + break; + case ikRefine: + xref = true; + line = "<"; + if (imp) + line += "Imp"; + else if (exp) + line += "Exp"; + else if (emb) + line += "Emb"; + line += "?> " + recN->MakePrototype(adr, false, true, false, true, false); + break; + default: + if (IsFlagSet(cfProcStart, pos)) + { + xref = true; + if (recN->kind == ikConstructor) + line = " " + recN->MakePrototype(adr, false, true, false, true, false); + else if (recN->kind == ikDestructor) + line = " " + recN->MakePrototype(adr, false, true, false, true, false); + else + { + line = "<"; + if (emb) line += "Emb"; + line += "Proc> " + recN->MakePrototype(adr, false, true, false, true, false); + } + } + break; + } + + if (kind >= ikRefine && kind <= ikFunc) + { + if (recN->procInfo->flags & PF_VIRTUAL) line += " virtual"; + if (recN->procInfo->flags & PF_DYNAMIC) line += " dynamic"; + if (recN->procInfo->flags & PF_EVENT) line += " event"; + } + if (line != "") + { + prefix = " " + Val2Str8(adr); + if (xref && recN->xrefs && recN->xrefs->Count) + { + prefix[1] ^= 2; + for (int m = 0; m < recN->xrefs->Count; m++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; + PUnitRec recU = GetUnit(recX->adr); + if (recU && !recU->kb) + { + prefix[1] ^= 4; + break; + } + } + prefix += " " + String(recN->xrefs->Count); + if (recN->xrefs->Count <= 9) + prefix += " "; + else if (recN->xrefs->Count <= 99) + prefix += " "; + } + line = prefix + " " + line; + lbUnitItems->Items->Add(line); + wid = canvas->TextWidth(line); + if (wid > maxwid) maxwid = wid; + } + } + + //Add initialization procedure + if (recU->iniadr) + { + line = " " + Val2Str8(recU->iniadr) + " Initialization;"; + lbUnitItems->Items->Add(line); + wid = canvas->TextWidth(line); + if (wid > maxwid) maxwid = wid; + } + //Add finalization procedure + if (recU->finadr) + { + line = " " + Val2Str8(recU->finadr) + " Finalization;"; + lbUnitItems->Items->Add(line); + wid = canvas->TextWidth(line); + if (wid > maxwid) maxwid = wid; + } + lbUnitItems->TopIndex = topIdx; + lbUnitItems->ItemIndex = itemIdx; + lbUnitItems->ScrollWidth = maxwid + 2; + lbUnitItems->ItemHeight = lbUnitItems->Canvas->TextHeight("T"); + lbUnitItems->Items->EndUpdate(); + + //if (AnalyzeThread) AnalyzeThread->Resume(); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitItemsDblClick(TObject *Sender) +{ + int idx = -1, len, size, refCnt, pos, bytes = 1024; + WORD* uses; + DWORD adr; + char *tmpBuf; + PInfoRec recN; + MTypeInfo tInfo; + String str; + char tkName[32], typeName[1024]; + + if (lbUnitItems->ItemIndex == -1) return; + + String item = lbUnitItems->Items->Strings[lbUnitItems->ItemIndex]; + //Xrefs? + if (item[11] == '<' || item[11] == '?') + sscanf(item.c_str() + 1, "%lX%s%s", &adr, tkName, typeName); + else + sscanf(item.c_str() + 1, "%lX%d%s%s", &adr, &refCnt, tkName, typeName); + String name = String(tkName); + pos = Adr2Pos(adr); + + if (SameText(name, "????")) + { + //Find end of unexplored Data + //Get first byte (use later for filtering code?data) + BYTE db = *(Code + pos); + + FExplorer_11011981->tsCode->TabVisible = true; + FExplorer_11011981->ShowCode(adr, bytes); + FExplorer_11011981->tsData->TabVisible = true; + FExplorer_11011981->ShowData(adr, bytes); + FExplorer_11011981->tsString->TabVisible = true; + FExplorer_11011981->ShowString(adr, 1024); + FExplorer_11011981->tsText->TabVisible = false; + FExplorer_11011981->WAlign = 0; + + FExplorer_11011981->btnDefCode->Enabled = true; + if (IsFlagSet(cfCode, pos)) FExplorer_11011981->btnDefCode->Enabled = false; + FExplorer_11011981->btnUndefCode->Enabled = false; + if (IsFlagSet(cfCode | cfData, pos)) FExplorer_11011981->btnUndefCode->Enabled = true; + + if (IsValidCode(adr) != -1 && db >= 0xF) + FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsCode; + else + FExplorer_11011981->pc1->ActivePage = FExplorer_11011981->tsData; + + if (FExplorer_11011981->ShowModal() == mrOk) + { + switch (FExplorer_11011981->DefineAs) + { + case DEFINE_AS_CODE: + recN = GetInfoRec(adr); + if (!recN) + recN = new InfoRec(pos, ikRefine); + else if (recN->kind < ikRefine || recN->kind > ikFunc) + { + delete recN; + recN = new InfoRec(pos, ikRefine); + } + + //AnalyzeProcInitial(adr); + AnalyzeProc1(adr, 0, 0, 0, false); + AnalyzeProc2(adr, true, true); + AnalyzeArguments(adr); + AnalyzeProc2(adr, true, true); + + if (!ContainsUnexplored(GetUnit(adr))) ShowUnits(true); + ShowUnitItems(GetUnit(adr), lbUnitItems->TopIndex, lbUnitItems->ItemIndex); + ShowCode(adr, 0, -1, -1); + break; + case DEFINE_AS_STRING: + break; + } + } + return; + } + + if (SameText(name, "") && tsClassView->TabVisible) + { + ShowClassViewer(adr); + return; + } + if (IsFlagSet(cfRTTI, pos)) + { + FTypeInfo_11011981->ShowRTTI(adr); + return; + } + if (SameText(name, "")) + { + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->Caption = "ResString"; + recN = GetInfoRec(adr); + FStringInfo_11011981->memStringInfo->Lines->Add(recN->rsInfo->value); + FStringInfo_11011981->ShowModal(); + return; + } + if (SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "")) + { + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->Caption = "String"; + recN = GetInfoRec(adr); + WideString ws = UnicodeEncode(recN->GetName(), CodePage); + FStringInfo_11011981->memStringInfo->Lines->Add(ws); + //FStringInfo_11011981->memStringInfo->Lines->Add((WideString)recN->GetName()); + FStringInfo_11011981->ShowModal(); + return; + } + if (SameText(name, "")) + { + FStringInfo_11011981->memStringInfo->Clear(); + FStringInfo_11011981->Caption = "String"; + recN = GetInfoRec(adr); + len = wcslen((wchar_t*)(Code + Adr2Pos(adr))); + size = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)(Code + Adr2Pos(adr)), len, 0, 0, 0, 0); + if (size) + { + tmpBuf = new char[size + 1]; + WideCharToMultiByte(CP_ACP, 0, (wchar_t*)(Code + Adr2Pos(adr)), len, tmpBuf, len, 0, 0); + FStringInfo_11011981->memStringInfo->Lines->Add(String(tmpBuf, len)); + delete[] tmpBuf; + FStringInfo_11011981->ShowModal(); + } + return; + } + /* + if (SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "")) + { + uses = KnowledgeBase.GetTypeUses(typeName); + idx = KnowledgeBase.GetTypeIdxByModuleIds(uses, typeName); + if (uses) delete[] uses; + + if (idx != -1) + { + idx = KnowledgeBase.TypeOffsets[idx].NamId; + if (KnowledgeBase.GetTypeInfo(idx, INFO_FIELDS | INFO_PROPS | INFO_METHODS, &tInfo)) + { + FTypeInfo_11011981->ShowKbInfo(&tInfo); + //as delete tInfo; + } + } + else + { + FTypeInfo_11011981->ShowRTTI(adr); + } + return; + } + */ + if (SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "")) + { + PROCHISTORYREC rec; + rec.adr = CurProcAdr; + rec.itemIdx = lbCode->ItemIndex; + rec.xrefIdx = lbCXrefs->ItemIndex; + rec.topIdx = lbCode->TopIndex; + ShowCode(adr, 0, -1, -1); + CodeHistoryPush(&rec); + pcWorkArea->ActivePage = tsCodeView; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitItemsKeyDown(TObject *Sender, + WORD &Key, TShiftState Shift) +{ + if (Key == VK_RETURN) lbUnitItemsDblClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitItemsClick(TObject *Sender) +{ + UnitItemsSearchFrom = lbUnitItems->ItemIndex; + WhereSearch = SEARCH_UNITITEMS; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitItemsDrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) +{ + int flags; + TColor _color; + TListBox *lb; + TCanvas *canvas; + String text, str; + + lb = (TListBox*)Control; + canvas = lb->Canvas; + SaveCanvas(canvas); + + if (Index < lb->Count) + { + flags = Control->DrawTextBiDiModeFlags(DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX); + if (!Control->UseRightToLeftAlignment()) + Rect.Left += 2; + else + Rect.Right -= 2; + canvas->FillRect(Rect); + + text = lb->Items->Strings[Index]; + //lb->ItemHeight = canvas->TextHeight(text); + str = text.SubString(2, text.Length() - 1); + //Procs with Xrefs + if (text[1] & 6) + { + //Xrefs from user units + if (text[1] & 4) + { + if (!State.Contains(odSelected)) + _color = TColor(0x00B000); //Green + else + _color = TColor(0xBBBBBB); //LightGray + } + //No Xrefs from user units, only from KB units + else + { + if (!State.Contains(odSelected)) + _color = TColor(0xC08000); //Blue + else + _color = TColor(0xBBBBBB); //LightGray + } + } + //Unresolved items + else if (text[1] & 1) + { + if (!State.Contains(odSelected)) + _color = TColor(0x8080FF); //Red + else + _color = TColor(0xBBBBBB); //LightGray + } + //Other + else + { + if (!State.Contains(odSelected)) + _color = TColor(0); //Black + else + _color = TColor(0xBBBBBB); //LightGray + } + Rect.Right = Rect.Left; + DrawOneItem(str, canvas, Rect, _color, flags); + } + RestoreCanvas(canvas); +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::lbUnitItemsMouseMove( + TObject *Sender, TShiftState Shift, int X, int Y) +{ + if (lbUnitItems->CanFocus()) ActiveControl = lbUnitItems; +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miSearchItemClick( + TObject *Sender) +{ + WhereSearch = SEARCH_UNITITEMS; + + FindDlg_11011981->cbText->Clear(); + for (int n = 0; n < UnitItemsSearchList->Count; n++) + FindDlg_11011981->cbText->AddItem(UnitItemsSearchList->Strings[n], 0); + + if (FindDlg_11011981->ShowModal() == mrOk && FindDlg_11011981->cbText->Text != "") + { + if (lbUnitItems->ItemIndex < 0) + UnitItemsSearchFrom = 0; + else + UnitItemsSearchFrom = lbUnitItems->ItemIndex; + + UnitItemsSearchText = FindDlg_11011981->cbText->Text; + if (UnitItemsSearchList->IndexOf(UnitItemsSearchText) == -1) UnitItemsSearchList->Add(UnitItemsSearchText); + FindText(UnitItemsSearchText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miEditFunctionIClick(TObject *Sender) +{ + int refCnt; + DWORD adr; + char tkName[32]; + + if (lbUnitItems->ItemIndex < 0) return; + + String item = lbUnitItems->Items->Strings[lbUnitItems->ItemIndex]; + //Xrefs? + if (item[11] == '<' || item[11] == '?') + sscanf(item.c_str() + 1, "%lX%s", &adr, tkName); + else + sscanf(item.c_str() + 1, "%lX%d%s", &adr, &refCnt, tkName); + + String name = String(tkName); + + if (SameText(name, "") || + //SameText(name, "") || + //SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + SameText(name, "") || + //SameText(name, "") || + SameText(name, "") //|| + //SameText(name, "") || + //SameText(name, "") || + //SameText(name, "") + ) + { + EditFunction(adr); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFMain_11011981::miCopyAddressIClick(TObject *Sender) +{ + CopyAddress(lbUnitItems->Items->Strings[lbUnitItems->ItemIndex], 1, 8); +} +//--------------------------------------------------------------------------- diff --git a/Threads.cpp b/Threads.cpp new file mode 100644 index 0000000..47c7eba --- /dev/null +++ b/Threads.cpp @@ -0,0 +1,3471 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Misc.h" +#include "Threads.h" +#pragma package(smart_init) +//--------------------------------------------------------------------------- +extern bool ProjectModified; +extern MKnowledgeBase KnowledgeBase; +extern TResourceInfo *ResInfo; + +//as: todo: remove all the global external dependencies +// all the required vars should be passed into the thread + +extern int dummy; +extern int DelphiVersion; +extern DWORD CurProcAdr; +extern DWORD CurUnitAdr; +extern bool ClassTreeDone; +extern SysProcInfo SysProcs[]; +extern SysProcInfo SysInitProcs[]; +extern BYTE *Code; +extern DWORD *Flags; +extern DWORD CodeSize; +extern DWORD CodeBase; +extern DWORD TotalSize; +extern PInfoRec *Infos; +extern TList *OwnTypeList; +extern int cVmtSelfPtr; +extern int cVmtParent; +extern int cVmtIntfTable; +extern int cVmtTypeInfo; +extern int cVmtDestroy; +extern int UnitsNum; +extern TList *ExpFuncList; +extern TList *VmtList; +extern TList *Units; +extern DWORD EP; +extern DWORD HInstanceVarAdr; +extern int LastResStrNo; +extern MDisasm Disasm; + +//as: print every 10th address in status bar (analysis time booster) +static const int SKIPADDR_COUNT = 10; +//--------------------------------------------------------------------------- +__fastcall TAnalyzeThread::TAnalyzeThread(TFMain_11011981* AForm, TFProgressBar* ApbForm, bool AllValues) + : TThread(true) +{ + Priority = tpLower; + mainForm = AForm; + pbForm = ApbForm; + all = AllValues; + adrCnt = 0; +} +//--------------------------------------------------------------------------- +__fastcall TAnalyzeThread::~TAnalyzeThread() +{ +} +//--------------------------------------------------------------------------- +int __fastcall TAnalyzeThread::GetRetVal() +{ + return ReturnValue; +} +//--------------------------------------------------------------------------- +//PopupMenu items!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//The Execute method is called when the thread starts +void __fastcall TAnalyzeThread::Execute() +{ + try + { + if (all) + { + //1 + StrapSysProcs(); + ReturnValue = 1; + CurProcAdr = EP; + UpdateCode(); + //2 + if (DelphiVersion != 2) + { + FindRTTIs(); + ReturnValue = 2; + UpdateUnits(); + } + //3 + if (DelphiVersion == 2) + FindVMTs2(); + else + FindVMTs(); + ReturnValue = 3; + UpdateVmtList(); + UpdateRTTIs(); + UpdateCode(); + //4 + StrapVMTs(); + ReturnValue = 4; + UpdateCode(); + //5 + ScanCode(); + ReturnValue = 5; + UpdateCode(); + //6 + ScanVMTs(); + ReturnValue = 6; + UpdateVmtList(); + UpdateCode(); + UpdateShortClassViewer(); + //7 + ScanConsts(); + ReturnValue = 7; + UpdateUnits(); + //8 + ScanGetSetStoredProcs(); + ReturnValue = 8; + //9 + FindStrings(); + ReturnValue = 9; + //10 + AnalyzeCode1(); + ReturnValue = 10; + UpdateCode(); + UpdateXrefs(); + //11 + ScanCode1(); + ReturnValue = 11; + UpdateCode(); + //12 + PropagateClassProps(); + ReturnValue = 12; + UpdateCode(); + //13 + FindTypeFields(); + ReturnValue = 13; + UpdateCode(); + //14 + FindPrototypes(); + ReturnValue = 14; + UpdateCode(); + //15 + AnalyzeCode2(true); + ReturnValue = 15; + UpdateCode(); + UpdateStrings(); + //16 + AnalyzeDC(); + ReturnValue = 16; + UpdateCode(); + //17 + AnalyzeCode2(false); + ReturnValue = 17; + UpdateCode(); + UpdateStrings(); + //18 + AnalyzeDC(); + ReturnValue = 18; + UpdateCode(); + //19 + AnalyzeCode2(false); + ReturnValue = LAST_ANALYZE_STEP; + UpdateCode(); + UpdateStrings(); + + UpdateBeforeClassViewer(); + } + //20 + FillClassViewer(); + ReturnValue = LAST_ANALYZE_STEP + 1; + UpdateClassViewer(); + } + catch (Exception& e) + { + Application->ShowException(&e); + } + + //as update main wnd about operation over + //only Post() here!) - async, otehrwise deadlock! + ::PostMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taFinished, 0); +} +//--------------------------------------------------------------------------- +const int PB_MAX_STEPS = 2048; +int __fastcall TAnalyzeThread::StartProgress(int pbMaxCount, const String& sbText) +{ + int stepSize = 1; + int pbSteps = pbMaxCount / stepSize; + if (pbSteps * stepSize < pbMaxCount) pbSteps++; + + if (pbMaxCount > PB_MAX_STEPS) + { + stepSize = 256; + while (pbSteps > PB_MAX_STEPS) + { + stepSize *= 2; + pbSteps = pbMaxCount / stepSize; + if (pbSteps * stepSize < pbMaxCount) pbSteps++; + } + } + ThreadAnalysisData* startOperation = new ThreadAnalysisData(pbSteps, sbText); + ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taStartPrBar, (long)startOperation);//Post + + return stepSize - 1; +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateProgress() +{ + if (!Terminated) + ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdatePrBar, 0);//Post +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::StopProgress() +{ +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateStatusBar(int adr) +{ + //if (Terminated) + // throw Exception("Termination request2"); + if (!Terminated) + { + ThreadAnalysisData* updateStatusBar = new ThreadAnalysisData(0, Val2Str8(adr)); + ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateStBar, (long)updateStatusBar); + } +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateStatusBar(const String& sbText) +{ + //if (Terminated) + // throw Exception("Termination request3"); + if (!Terminated) + { + ThreadAnalysisData* updateStatusBar = new ThreadAnalysisData(0, sbText); + ::SendMessage(pbForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateStBar, (long)updateStatusBar); + } +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateAddrInStatusBar(DWORD adr) +{ + if (!Terminated) + { + adrCnt++; + if (adrCnt == SKIPADDR_COUNT) + { + UpdateStatusBar(adr); + adrCnt = 0; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateUnits() +{ + if (!Terminated) + { + long isLastStep = long(ReturnValue == LAST_ANALYZE_STEP); + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateUnits, isLastStep); + } +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateRTTIs() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateRTTIs, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateVmtList() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateVmtList, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateStrings() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateStrings, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateCode() +{ + if (!Terminated) + { + UpdateUnits(); + //cant use Post here, there are some global shared vars! + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateCode, 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateXrefs() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateXrefs, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateShortClassViewer() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateShortClassViewer, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateClassViewer() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateClassViewer, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::UpdateBeforeClassViewer() +{ + if (!Terminated) + ::SendMessage(mainForm->Handle, WM_UPDANALYSISSTATUS, (int)taUpdateBeforeClassViewer, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::StrapSysProcs() +{ + int n, Idx, pos; + MProcInfo aInfo, *pInfo; + + WORD moduleID = KnowledgeBase.GetModuleID("System"); + for (n = 0; SysProcs[n].name && !Terminated; n++) + { + Idx = KnowledgeBase.GetProcIdx(moduleID, SysProcs[n].name); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, &aInfo); + if (SysProcs[n].impAdr) + { + mainForm->StrapProc(Adr2Pos(SysProcs[n].impAdr), Idx, pInfo, false, 6); + } + else + { + pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); + if (pInfo && pos != -1) + { + mainForm->StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); + } + } + } + } + } + + moduleID = KnowledgeBase.GetModuleID("SysInit"); + for (n = 0; SysInitProcs[n].name && !Terminated; n++) + { + Idx = KnowledgeBase.GetProcIdx(moduleID, SysInitProcs[n].name); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + pInfo = KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, &aInfo); + pos = KnowledgeBase.ScanCode(Code, Flags, CodeSize, pInfo); + if (pInfo && pos != -1) + { + mainForm->StrapProc(pos, Idx, pInfo, true, pInfo->DumpSz); + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::FindRTTIs() +{ + BYTE paramCnt, numOps, methodKind, flags; + WORD dw, Count, methCnt; + DWORD typInfo, baseTypeAdr, dd, procSig; + int j, n, m, minValue, maxValue, elNum, pos, instrLen; + PInfoRec recN, recN1; + String name, unitName; + DISINFO DisInfo; + + int stepMask = StartProgress(CodeSize, "Find Types"); + + for (int i = 0; i < CodeSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + DWORD adr = *((DWORD*)(Code + i)); + if (IsValidImageAdr(adr) && adr == Pos2Adr(i) + 4) + { + //Euristica - look at byte Code + i - 3 - may be case (jmp [adr + reg*4]) + instrLen = Disasm.Disassemble(Code + i - 3, (__int64)Pos2Adr(i) - 3, &DisInfo, 0); + if (instrLen > 3 && DisInfo.Branch && DisInfo.Offset == adr) continue; + + DWORD typeAdr = adr - 4; + BYTE typeKind = Code[i + 4]; + if (typeKind == ikUnknown || typeKind > ikProcedure) continue; + + BYTE len = Code[i + 5]; + if (!IsValidName(len, i + 6)) continue; + + n = i + 6 + len; + SetFlag(cfRTTI, i); + unitName = ""; + + String TypeName = GetTypeName(adr); + UpdateStatusBar(TypeName); + + switch (typeKind) + { + case ikInteger: //1 + n++; //ordType + n += 4; //MinVal + n += 4; //MaxVal + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikChar: //2 + n++; //ordType + n += 4; //MinVal + n += 4; //MaxVal + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikEnumeration: //3 + n++; //ordType + minValue = *((int*)(Code + n)); n += 4; + maxValue = *((int*)(Code + n)); n += 4; + //BaseType + baseTypeAdr = *((DWORD*)(Code + n)); n += 4; + + if (baseTypeAdr == typeAdr) + { + if (SameText(TypeName, "ByteBool") || + SameText(TypeName, "WordBool") || + SameText(TypeName, "LongBool")) + { + minValue = 0; + maxValue = 1; + } + for (j = minValue; j <= maxValue; j++) + { + len = Code[n]; + n += len + 1; + } + } + /* + //UnitName + len = Code[n]; + if (IsValidName(len, n + 1)) + { + unitName = String((char*)(Code + n + 1), len).Trim(); + SetUnitName(recU, unitName); + } + n += len + 1; + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); n += dw; + } + */ + SetFlags(cfData, i, n - i); + break; + case ikFloat: //4 + n++; //FloatType + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikString: //5 + n++; //MaxLength + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikSet: //6 + n += 1 + 4; //ordType+CompType + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikClass: //7 + n += 4; //classVMT + n += 4; //ParentInfo + n += 2; //PropCount + //UnitName + len = Code[n]; + if (IsValidName(len, n + 1)) + { + unitName = String((char*)(Code + n + 1), len).Trim(); + //FMain_11011981->SetUnitName(recU, unitName); + } + n += len + 1; + //PropData + Count = *((WORD*)(Code + n)); n += 2; + for (j = 0; j < Count; j++) + { + //TPropInfo + n += 26; + len = Code[n]; n += len + 1; + } + if (DelphiVersion >= 2010) + { + //PropDataEx + Count = *((WORD*)(Code + n)); n += 2; + for (j = 0; j < Count; j++) + { + //TPropInfoEx + //Flags + n++; + //Info + typInfo = *((DWORD*)(Code + n)); n += 4; + pos = Adr2Pos(typInfo); + len = Code[pos + 26]; + SetFlags(cfData, pos, 27 + len); + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + if (DelphiVersion >= 2012) + { + //ArrayPropCount + Count = *((WORD*)(Code + n)); n += 2; + //ArrayPropData + for (j = 0; j < Count; j++) + { + //Flags + n++; + //ReadIndex + n += 2; + //WriteIndex + n += 2; + //Name + len = Code[n]; n += len + 1; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + } + } + SetFlags(cfData, i, n - i); + break; + case ikMethod: //8 + //MethodKind + methodKind = Code[n]; n++; //0 (mkProcedure) or 1 (mkFunction) + paramCnt = Code[n]; n++; + for (j = 0; j < paramCnt; j++) + { + n++; //Flags + len = Code[n]; n += len + 1; //ParamName + len = Code[n]; n += len + 1; //TypeName + } + if (methodKind) + { + //ResultType + len = Code[n]; n += len + 1; + if (DelphiVersion > 6) + { + //ResultTypeRef + n += 4; + } + } + if (DelphiVersion > 6) + { + //CC + n++; + //ParamTypeRefs + n += 4*paramCnt; + if (DelphiVersion >= 2010) + { + //MethSig + procSig = *((DWORD*)(Code + n)); n += 4; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + pos = Adr2Pos(procSig); + else + pos = i + procSig; + m = 0; + //Flags + flags = Code[pos]; m++; + if (flags != 0xFF) + { + //CC + m++; + //ResultType + m += 4; + //ParamCount + paramCnt = Code[pos + m]; m++; + for (j = 0; j < paramCnt; j++) + { + //Flags + m++; + //ParamType + m += 4; + //Name + len = Code[pos + m]; m += len + 1; + //AttrData + dw = *((WORD*)(Code + pos + m)); + m += dw;//ATR!! + } + } + SetFlags(cfData, pos, m); + } + } + } + SetFlags(cfData, i, n - i); + break; + case ikWChar: //9 + n++; //ordType + n += 4; //MinVal + n += 4; //MaxVal + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikLString: //0xA + //CodePage + if (DelphiVersion >= 2009) n += 2; + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikWString: //0xB + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikVariant: //0xC + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikArray: //0xD + n += 4; //Size + n += 4; //ElCount + n += 4; //ElType + if (DelphiVersion >= 2010) + { + //DimCount + paramCnt = Code[n]; n++; + for (j = 0; j < paramCnt; j++) + { + //Dims + n += 4; + } + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikRecord: //0xE + n += 4; //Size + elNum = *((int*)(Code + n)); n += 4; //ManagedFldCount + for (j = 0; j < elNum; j++) + { + n += 4; //TypeRef + n += 4; //FldOffset + } + + if (DelphiVersion >= 2010) + { + numOps = Code[n]; n++; //NumOps + for (j = 0; j < numOps; j++) //RecOps + { + n += 4; + } + elNum = *((int*)(Code + n)); n += 4; //RecFldCnt + for (j = 0; j < elNum; j++) + { + n += 4; //TypeRef + n += 4; //FldOffset + n++; //Flags + len = Code[n]; n += len + 1; //Name + dw = *((WORD*)(Code + n)); + if (dw != 2) + dummy = 1; + n += dw;//ATR!! + } + dw = *((WORD*)(Code + n)); + if (dw != 2) + dummy = 1; + n += dw;//ATR!! + if (DelphiVersion >= 2012) + { + methCnt = *((WORD*)(Code + n)); n += 2; + for (j = 0; j < methCnt; j++) + { + n++; //Flags + n += 4; //Code + len = Code[n]; n += len + 1; //Name + //ProcedureSignature + //Flags + flags = Code[n]; n++; + if (flags != 0xFF) + { + //CC + n++; + //ResultType + n += 4; + //ParamCnt + paramCnt = Code[n]; n++; + //Params + for (m = 0; m < paramCnt; m++) + { + n++; //Flags + n += 4; //ParamType + len = Code[n]; n += len + 1; //Name + dw = *((WORD*)(Code + n)); + if (dw != 2) + dummy = 1; + n += dw;//ATR!! + } + } + dw = *((WORD*)(Code + n)); + if (dw != 2) + dummy = 1; + n += dw;//ATR!! + } + } + } + SetFlags(cfData, i, n - i); + break; + case ikInterface: //0xF + n += 4; //IntfParent + n++; //IntfFlags + n += 16; //GUID + //UnitName + len = Code[n]; + if (IsValidName(len, n + 1)) + { + unitName = String((char*)(Code + n + 1), len).Trim(); + //FMain_11011981->SetUnitName(recU, unitName); + } + n += len + 1; + //PropCount + Count = *((WORD*)(Code + n)); n += 2; + if (DelphiVersion >= 6) + { + //RttiCount + dw = *((WORD*)(Code + n)); n += 2; + if (dw != 0xFFFF) + { + if (DelphiVersion >= 2010) + { + for (j = 0; j < Count; j++) + { + //Name + len = Code[n]; n += len + 1; + //Kind + methodKind = Code[n]; n++; + //CallConv + n++; + //ParamCount + paramCnt = Code[n]; n++; + for (m = 0; m < paramCnt; m++) + { + //Flags + n++; + //ParamName + len = Code[n]; n += len + 1; + //TypeName + len = Code[n]; n += len + 1; + //ParamType + n += 4; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + if (methodKind) + { + //ResultTypeName + len = Code[n]; n += len + 1; + if (len) + { + //ResultType + n += 4; + //////////////////////////// Insert by Pigrecos + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + //////////////////////////// + } + } + } + } + else + { + for (j = 0; j < Count; j++) + { + //PropType + n += 4; + //GetProc + n += 4; + //SetProc + n += 4; + //StoredProc + n += 4; + //Index + n += 4; + //Default + n += 4; + //NameIndex + n += 2; + //Name + len = Code[n]; n += len + 1; + } + } + } + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + } + SetFlags(cfData, i, n - i); + break; + case ikInt64: //0x10 + n += 8; //MinVal + n += 8; //MaxVal + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikDynArray: //0x11 + n += 4; //elSize + n += 4; //elType + n += 4; //varType + if (DelphiVersion >= 6) + { + n += 4; //elType2 + //UnitName + len = Code[n]; + if (IsValidName(len, n + 1)) + { + unitName = String((char*)(Code + n + 1), len).Trim(); + //FMain_11011981->SetUnitName(recU, unitName); + } + n += len + 1; + } + if (DelphiVersion >= 2010) + { + //DynArrElType + n += 4; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikUString: //0x12 + if (DelphiVersion >= 2010) + { + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + } + SetFlags(cfData, i, n - i); + break; + case ikClassRef: //0x13 + //InstanceType + n += 4; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + SetFlags(cfData, i, n - i); + break; + case ikPointer: //0x14 + //RefType + n += 4; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + SetFlags(cfData, i, n - i); + break; + case ikProcedure: //0x15 + //MethSig + procSig = *((DWORD*)(Code + n)); n += 4; + //AttrData + dw = *((WORD*)(Code + n)); + n += dw;//ATR!! + SetFlags(cfData, i, n - i); + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + pos = Adr2Pos(procSig); + else + pos = i + procSig; + m = 0; + //Flags + flags = Code[pos]; m++; + if (flags != 0xFF) + { + //CC + m++; + //ResultType + m += 4; + //ParamCount + paramCnt = Code[pos + m]; m++; + for (j = 0; j < paramCnt; j++) + { + //Flags+ParamType + m += 5; + //Name + len = Code[pos + m]; m += len + 1; + //AttrData + dw = *((WORD*)(Code + pos + m)); + m += dw;//ATR!! + } + } + SetFlags(cfData, pos, m); + } + break; + } + + if (!Infos[i]) + { + recN = new InfoRec(i, typeKind); + recN->SetName(TypeName); + } + PTypeRec recT = new TypeRec; + recT->kind = typeKind; + recT->adr = typeAdr; + //if (unitName != "") TypeName += " (" + unitName + ")"; + recT->name = TypeName; + OwnTypeList->Add(recT); + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::FindVMTs2() +{ + BYTE len; + WORD Num16; + int i, pos, bytes, _ap, _ap0; + DWORD Num32; + String TypeName; + + int stepMask = StartProgress(CodeSize, "Find Virtual Method Tables D2"); + + for (i = 0; i < CodeSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfCode | cfData, i)) continue; + + DWORD selfPtr = *((DWORD*)(Code + i)); + if (selfPtr && !IsValidImageAdr(selfPtr)) continue; + + DWORD initTableAdr = *((DWORD*)(Code + i + 4)); + if (initTableAdr) + { + if (!IsValidImageAdr(initTableAdr)) continue; + if (*(Code + pos) != 0xE) continue; + pos = Adr2Pos(initTableAdr); + Num32 = *((DWORD*)(Code + pos + 5)); + if (Num32 > 10000) continue; + } + + DWORD typeInfoAdr = *((DWORD*)(Code + i + 8)); + if (typeInfoAdr) + { + if (!IsValidImageAdr(typeInfoAdr)) continue; + //typeInfoAdr contains kind of type + pos = Adr2Pos(typeInfoAdr); + BYTE typeKind = *(Code + pos); + if (typeKind > tkVariant) continue; + //len = *(Code + pos + 1); + //if (!IsValidName(len, pos + 2)) continue; + } + + DWORD fieldTableAdr = *((DWORD*)(Code + i + 0xC)); + if (fieldTableAdr) + { + if (!IsValidImageAdr(fieldTableAdr)) continue; + pos = Adr2Pos(fieldTableAdr); + Num16 = *((WORD*)(Code + pos)); + if (Num16 > 10000) continue; + } + + DWORD methodTableAdr = *((DWORD*)(Code + i + 0x10)); + if (methodTableAdr) + { + if (!IsValidImageAdr(methodTableAdr)) continue; + pos = Adr2Pos(methodTableAdr); + Num16 = *((WORD*)(Code + pos)); + if (Num16 > 10000) continue; + } + + DWORD dynamicTableAdr = *((DWORD*)(Code + i + 0x14)); + if (dynamicTableAdr) + { + if (!IsValidImageAdr(dynamicTableAdr)) continue; + pos = Adr2Pos(dynamicTableAdr); + Num16 = *((WORD*)(Code + pos)); + if (Num16 > 10000) continue; + } + + DWORD classNameAdr = *((DWORD*)(Code + i + 0x18)); + if (!classNameAdr || !IsValidImageAdr(classNameAdr)) continue; + + //_ap = Adr2Pos(classNameAdr); + //len = *(Code + _ap); + //if (!IsValidName(len, _ap + 1)) continue; + + DWORD instanceSize = *((DWORD*)(Code + i + 0x1C)); + if (!instanceSize) continue; + + DWORD parentAdr = *((DWORD*)(Code + i + 0x20)); + if (parentAdr && !IsValidImageAdr(parentAdr)) continue; + + DWORD defaultHandlerAdr = *((DWORD*)(Code + i + 0x24)); + if (defaultHandlerAdr && !IsValidImageAdr(defaultHandlerAdr)) continue; + + DWORD newInstanceAdr = *((DWORD*)(Code + i + 0x28)); + if (newInstanceAdr && !IsValidImageAdr(newInstanceAdr)) continue; + + DWORD freeInstanceAdr = *((DWORD*)(Code + i + 0x2C)); + if (freeInstanceAdr && !IsValidImageAdr(freeInstanceAdr)) continue; + + DWORD destroyAdr = *((DWORD*)(Code + i + 0x30)); + if (destroyAdr && !IsValidImageAdr(destroyAdr)) continue; + + DWORD classVMT = Pos2Adr(i) - cVmtSelfPtr; + if (Adr2Pos(classVMT) < 0) continue; + + int StopAt = GetStopAt(classVMT); + if (i + StopAt - classVMT - cVmtSelfPtr >= CodeSize) continue; + + _ap = Adr2Pos(classNameAdr); + if (_ap <= 0) continue; + len = *(Code + _ap); + TypeName = String((char*)(Code + _ap + 1), len); + UpdateStatusBar(TypeName); + + //Add to TypeList + PTypeRec recT = new TypeRec; + recT->kind = ikVMT; + recT->adr = Pos2Adr(i); + recT->name = TypeName; + OwnTypeList->Add(recT); + + //Name already used + SetFlags(cfData, _ap, len + 1); + + if (!Infos[i]) + { + PInfoRec recN = new InfoRec(i, ikVMT); + recN->SetName(TypeName); + } + //InitTable + if (initTableAdr) + { + pos = Adr2Pos(initTableAdr); bytes = 0; + pos++; bytes++; //skip 0xE + pos++; bytes++; //unknown byte + pos += 4; bytes += 4; //unknown dd + Num32 = *((DWORD*)(Code + pos)); bytes += 4; + + for (int m = 0; m < Num32; m++) + { + //Type offset (Information about types already extracted) + bytes += 4; + //FieldOfs + bytes += 4; + } + //InitTable used + SetFlags(cfData, Adr2Pos(initTableAdr), bytes); + } + //FieldTable + if (fieldTableAdr) + { + pos = Adr2Pos(fieldTableAdr); bytes = 0; + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + //TypesTab + DWORD typesTab = *((DWORD*)(Code + pos)); pos += 4; bytes += 4; + + for (int m = 0; m < Num16; m++) + { + //FieldOfs + pos += 4; bytes += 4; + //idx + pos += 2; bytes += 2; + len = Code[pos]; pos++; bytes++; + //name + pos += len; bytes += len; + } + //FieldTable used + SetFlags(cfData, Adr2Pos(fieldTableAdr), bytes); + //Use TypesTab + Num16 = *((WORD*)(Code + Adr2Pos(typesTab))); + SetFlags(cfData, Adr2Pos(typesTab), 2 + Num16*4); + } + //MethodTable + if (methodTableAdr) + { + pos = Adr2Pos(methodTableAdr); bytes = 0; + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + + for (int m = 0; m < Num16; m++) + { + //Length of Method Description + WORD skipNext = *((WORD*)(Code + pos)); pos += skipNext; bytes += skipNext; + } + //MethodTable used + SetFlags(cfData, Adr2Pos(methodTableAdr), bytes); + } + //DynamicTable + if (dynamicTableAdr) + { + pos = Adr2Pos(dynamicTableAdr); bytes = 0; + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + + for (int m = 0; m < Num16; m++) + { + //Msg + bytes += 2; + //ProcAdr + bytes += 4; + } + //DynamicTable used + SetFlags(cfData, Adr2Pos(dynamicTableAdr), bytes); + } + + //DWORD StopAt = GetStopAt(classVMT); + //Èñïîëüçîâàëè âèðòóàëüíóþ òàáëèöó + SetFlags(cfData, i, StopAt - classVMT - cVmtSelfPtr); + + PUnitRec recU = mainForm->GetUnit(classVMT); + if (recU) + { + if (typeInfoAdr) //extract unit name + { + _ap0 = Adr2Pos(typeInfoAdr); _ap = _ap0; + BYTE b = Code[_ap]; _ap++; + if (b != 7) continue; + len = Code[_ap]; _ap++; + if (!IsValidName(len, _ap)) continue; + _ap += len + 10; + len = Code[_ap]; _ap++; + if (!IsValidName(len, _ap)) continue; + String unitName = String((char*)(Code + _ap), len).Trim(); _ap += len; + FMain_11011981->SetUnitName(recU, unitName); + //Use information about Unit + SetFlags(cfData, _ap0, _ap - _ap0); + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +//Collect information from VMT structure +void __fastcall TAnalyzeThread::FindVMTs() +{ + WORD Num16; + int bytes, pos, posv, EntryCount; + DWORD Num32; + + int stepMask = StartProgress(TotalSize, "Find Virtual Method Tables"); + + for (int i = 0; i < TotalSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfCode | cfData, i)) continue; + DWORD adr = *((DWORD*)(Code + i)); //Points to vmt0 (cVmtSelfPtr) + if (IsValidImageAdr(adr) && Pos2Adr(i) == adr + cVmtSelfPtr) + { + DWORD classVMT = adr; + DWORD StopAt = GetStopAt(classVMT); + //if (i + StopAt - classVMT - cVmtSelfPtr >= CodeSize) continue; + + DWORD intfTableAdr = *((DWORD*)(Code + i + 4)); + if (intfTableAdr) + { + if (!IsValidImageAdr(intfTableAdr)) continue; + pos = Adr2Pos(intfTableAdr); + EntryCount = *((DWORD*)(Code + pos)); + if (EntryCount > 10000) continue; + } + + DWORD autoTableAdr = *((DWORD*)(Code + i + 8)); + if (autoTableAdr) + { + if (!IsValidImageAdr(autoTableAdr)) continue; + pos = Adr2Pos(autoTableAdr); + EntryCount = *((DWORD*)(Code + pos)); + if (EntryCount > 10000) continue; + } + + DWORD initTableAdr = *((DWORD*)(Code + i + 0xC)); + if (initTableAdr) + { + if (!IsValidImageAdr(initTableAdr)) continue; + pos = Adr2Pos(initTableAdr); + Num32 = *((DWORD*)(Code + pos + 6)); + if (Num32 > 10000) continue; + } + + DWORD typeInfoAdr = *((DWORD*)(Code + i + 0x10)); + if (typeInfoAdr) + { + if (!IsValidImageAdr(typeInfoAdr)) continue; + //Ïî àäðåñó typeInfoAdr äîëæíû áûòü äàííûå î òèïå, íà÷èíàþùèåñÿ ñ îïðåäåëåííîé èíôîðìàöèè + pos = Adr2Pos(typeInfoAdr); + BYTE typeKind = *(Code + pos); + if (typeKind > ikProcedure) continue; + //len = *(Code + pos + 1); + //if (!IsValidName(len, pos + 2)) continue; + } + + DWORD fieldTableAdr = *((DWORD*)(Code + i + 0x14)); + if (fieldTableAdr) + { + if (!IsValidImageAdr(fieldTableAdr)) continue; + pos = Adr2Pos(fieldTableAdr); + Num16 = *((WORD*)(Code + pos)); + if (Num16 > 10000) continue; + } + + DWORD methodTableAdr = *((DWORD*)(Code + i + 0x18)); + if (methodTableAdr) + { + if (!IsValidImageAdr(methodTableAdr)) continue; + pos = Adr2Pos(methodTableAdr); + Num16 = *((WORD*)(Code + pos)); + if (Num16 > 10000) continue; + } + + DWORD dynamicTableAdr = *((DWORD*)(Code + i + 0x1C)); + if (dynamicTableAdr) + { + if (!IsValidImageAdr(dynamicTableAdr)) continue; + pos = Adr2Pos(dynamicTableAdr); + Num16 = *((WORD*)(Code + pos)); + if (Num16 > 10000) continue; + } + + DWORD classNameAdr = *((DWORD*)(Code + i + 0x20)); + if (!classNameAdr || !IsValidImageAdr(classNameAdr)) continue; + + //n = Adr2Pos(classNameAdr); + //len = *(Code + n); + //if (!IsValidName(len, n + 1)) continue; + + DWORD parentAdr = *((DWORD*)(Code + i + 0x28)); + if (parentAdr && !IsValidImageAdr(parentAdr)) continue; + + int n = Adr2Pos(classNameAdr); + BYTE len = Code[n]; + //if (!IsValidName(len, n + 1)) continue; + String TypeName = String((char*)(Code + n + 1), len); + UpdateStatusBar(TypeName); + + //Add to TypeList + PTypeRec recT = new TypeRec; + recT->kind = ikVMT; + recT->adr = Pos2Adr(i); + recT->name = TypeName; + OwnTypeList->Add(recT); + + //Name already use + SetFlags(cfData, n, len + 1); + + if (!GetInfoRec(Pos2Adr(i))) + { + PInfoRec recN = new InfoRec(i, ikVMT); + recN->SetName(TypeName); + } + SetFlag(cfData, i); + + //IntfTable + DWORD vTableAdr; + + if (intfTableAdr) + { + pos = Adr2Pos(intfTableAdr); bytes = 0; + SetFlag(cfData | cfVTable, pos); + EntryCount = *((DWORD*)(Code + pos)); pos += 4; bytes += 4; + for (int m = 0; m < EntryCount; m++) + { + //GUID + pos += 16; bytes += 16; + vTableAdr = *((DWORD*)(Code + pos)); pos += 4; bytes += 4; + if (IsValidImageAdr(vTableAdr)) SetFlag(cfData | cfVTable, Adr2Pos(vTableAdr)); + //IOffset + pos += 4; bytes += 4; + if (DelphiVersion > 3) + { + //ImplGetter + pos += 4; bytes += 4; + } + } + //Intfs + if (DelphiVersion >= 2012) bytes += EntryCount * 4; + + //Use IntfTable + SetFlags(cfData, Adr2Pos(intfTableAdr), bytes); + //Second pass (to use already set flags) + pos = Adr2Pos(intfTableAdr) + 4; + for (int m = 0; m < EntryCount; m++) + { + //Skip GUID + pos += 16; + vTableAdr = *((DWORD*)(Code + pos)); pos += 4; + //IOffset + pos += 4; + if (DelphiVersion > 3) + { + //ImplGetter + pos += 4; + } + //Use VTable + if (IsValidImageAdr(vTableAdr)) + { + DWORD vEnd = vTableAdr; + DWORD vStart = vTableAdr; + posv = Adr2Pos(vTableAdr); bytes = 0; + for (int k = 0;; k++) + { + if (Pos2Adr(posv) == intfTableAdr) break; + DWORD vAdr = *((DWORD*)(Code + posv)); posv += 4; bytes += 4; + if (vAdr && vAdr < vStart) vStart = vAdr; + } + //Use VTable + SetFlags(cfData, Adr2Pos(vEnd), bytes); + //Leading always byte CC + vStart--; + //Use all refs + SetFlags(cfData, Adr2Pos(vStart), vEnd - vStart); + } + } + } + //AutoTable + if (autoTableAdr) + { + pos = Adr2Pos(autoTableAdr); bytes = 0; + EntryCount = *((DWORD*)(Code + pos)); pos += 4; bytes += 4; + for (int m = 0; m < EntryCount; m++) + { + //DispID + pos += 4; bytes += 4; + //NameAdr + DWORD pos1 = Adr2Pos(*((DWORD*)(Code + pos))); pos += 4; bytes += 4; + len = Code[pos1]; + //Use name + SetFlags(cfData, pos1, len + 1); + //Flags + pos += 4; bytes += 4; + //ParamsAdr + pos1 = Adr2Pos(*((DWORD*)(Code + pos))); pos += 4; bytes += 4; + BYTE ParamCnt = Code[pos1 + 1]; + //Use Params + SetFlags(cfData, pos1, ParamCnt + 2); + //AddressAdr + pos += 4; bytes += 4; + } + //Use AutoTable + SetFlags(cfData, Adr2Pos(autoTableAdr), bytes); + } + //InitTable + if (initTableAdr) + { + pos = Adr2Pos(initTableAdr); bytes = 0; + //Skip 0xE + pos++; bytes++; + //Unknown byte + pos++; bytes++; + //Unknown dword + pos += 4; bytes += 4; + Num32 = *((DWORD*)(Code + pos)); bytes += 4; + + for (int m = 0; m < Num32; m++) + { + //TypeOfs (information about types is already extracted) + bytes += 4; + //FieldOfs + bytes += 4; + } + //Use InitTable + SetFlags(cfData, Adr2Pos(initTableAdr), bytes); + } + //FieldTable + if (fieldTableAdr) + { + pos = Adr2Pos(fieldTableAdr); bytes = 0; + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + //TypesTab + DWORD typesTab = *((DWORD*)(Code + pos)); pos += 4; bytes += 4; + + for (int m = 0; m < Num16; m++) + { + //Offset + pos += 4; bytes += 4; + //Idx + pos += 2; bytes += 2; + //Name + len = Code[pos]; pos++; bytes++; + pos += len; bytes += len; + } + //Use TypesTab + if (typesTab) + { + Num16 = *((WORD*)(Code + Adr2Pos(typesTab))); + SetFlags(cfData, Adr2Pos(typesTab), 2 + Num16*4); + } + //Extended Information + if (DelphiVersion >= 2010) + { + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + for (int m = 0; m < Num16; m++) + { + //Flags + pos++; bytes++; + //TypeRef + pos += 4; bytes += 4; + //Offset + pos += 4; bytes += 4; + //Name + len = Code[pos]; pos++; bytes++; + pos += len; bytes += len; + //AttrData + WORD dw = *((WORD*)(Code + pos)); + pos += dw; bytes += dw;//ATR!! + } + } + //Use FieldTable + SetFlags(cfData, Adr2Pos(fieldTableAdr), bytes); + } + //MethodTable + if (methodTableAdr) + { + pos = Adr2Pos(methodTableAdr); bytes = 0; + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + + for (int m = 0; m < Num16; m++) + { + //Len + WORD skipBytes = *((WORD*)(Code + pos)); pos += skipBytes; bytes += skipBytes; + } + if (DelphiVersion >= 2010) + { + Num16 = *((WORD*)(Code + pos)); pos += 2; bytes += 2; + for (int m = 0; m < Num16; m++) + { + //MethodEntry + DWORD methodEntry = *((DWORD*)(Code + pos)); pos += 4; bytes += 4; + WORD skipBytes = *((WORD*)(Code + Adr2Pos(methodEntry))); + SetFlags(cfData, Adr2Pos(methodEntry), skipBytes); + //Flags + pos += 2; bytes += 2; + //VirtualIndex + pos += 2; bytes += 2; + } + if (DelphiVersion >= 2012) + { + //VirtCount + bytes += 2; + } + } + //Use MethodTable + SetFlags(cfData, Adr2Pos(methodTableAdr), bytes); + } + //DynamicTable + if (dynamicTableAdr) + { + pos = Adr2Pos(dynamicTableAdr); bytes = 0; + Num16 = *((WORD*)(Code + pos)); bytes += 2; + for (int m = 0; m < Num16; m++) + { + //Msg+ProcAdr + bytes += 6; + } + //Use DynamicTable + SetFlags(cfData, Adr2Pos(dynamicTableAdr), bytes); + } + + //DWORD StopAt = GetStopAt(classVMT); + //Use Virtual Table + SetFlags(cfData, i, StopAt - classVMT - cVmtSelfPtr); + + PUnitRec recU = mainForm->GetUnit(classVMT); + if (recU) + { + adr = *((DWORD*)(Code + i - cVmtSelfPtr + cVmtTypeInfo)); + if (adr && IsValidImageAdr(adr)) + { + //Extract unit name + pos = Adr2Pos(adr); bytes = 0; + BYTE b = Code[pos]; pos++; bytes++; + if (b != 7) continue; + len = Code[pos]; pos++; bytes++; + if (!IsValidName(len, pos)) continue; + pos += len + 10; bytes += len + 10; + len = Code[pos]; pos++; bytes++; + if (!IsValidName(len, pos)) continue; + String unitName = String((char*)(Code + pos), len).Trim(); bytes += len; + FMain_11011981->SetUnitName(recU, unitName); + //Use information about Unit (including previous dword) + SetFlags(cfData, Adr2Pos(adr) - 4, bytes + 4); + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::StrapVMTs() +{ + int stepMask = StartProgress(TotalSize, "Strap Virtual Method Tables"); + + MConstInfo cInfo; + for (int i = 0; i < TotalSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + PInfoRec recN = GetInfoRec(Pos2Adr(i)); + if (recN && recN->kind == ikVMT) + { + String _name = recN->GetName(); + String ConstName = "_DV_" + _name; + WORD *uses = KnowledgeBase.GetConstUses(ConstName.c_str()); + int ConstIdx = KnowledgeBase.GetConstIdx(uses, ConstName.c_str()); + if (ConstIdx != -1) + { + ConstIdx = KnowledgeBase.ConstOffsets[ConstIdx].NamId; + if (KnowledgeBase.GetConstInfo(ConstIdx, INFO_DUMP, &cInfo)) + { + UpdateStatusBar(_name); + mainForm->StrapVMT(i + 4, ConstIdx, &cInfo); + } + } + if (uses) delete[] uses; + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::FindTypeFields() +{ + int typeSize; + int stepMask = StartProgress(TotalSize, "Find Type Fields"); + + MTypeInfo atInfo; + MTypeInfo *tInfo = &atInfo; + + for (int i = 0; i < TotalSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + PInfoRec recN = GetInfoRec(Pos2Adr(i)); + if (recN && recN->kind == ikVMT) + { + DWORD vmtAdr = Pos2Adr(i) - cVmtSelfPtr; + PUnitRec recU = mainForm->GetUnit(vmtAdr); + if (recU) + { + for (int u = 0; u < recU->names->Count && !Terminated; u++) + { + WORD ModuleID = KnowledgeBase.GetModuleID(recU->names->Strings[u].c_str()); + WORD *uses = KnowledgeBase.GetModuleUses(ModuleID); + //Find Type to extract information about fields + int TypeIdx = KnowledgeBase.GetTypeIdxByModuleIds(uses, recN->GetName().c_str()); + if (TypeIdx != -1) + { + TypeIdx = KnowledgeBase.TypeOffsets[TypeIdx].NamId; + if(KnowledgeBase.GetTypeInfo(TypeIdx, INFO_FIELDS, tInfo)) + { + if (tInfo->Fields) + { + UpdateStatusBar(tInfo->TypeName); + BYTE *p = tInfo->Fields; + FIELDINFO fInfo; + for (int n = 0; n < tInfo->FieldsNum; n++) + { + fInfo.Scope = *p; p++; + fInfo.Offset = *((int*)p); p += 4; + fInfo.Case = *((int*)p); p += 4; + WORD Len = *((WORD*)p); p += 2; + fInfo.Name = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + fInfo.Type = TrimTypeName(String((char*)p, Len)); p += Len + 1; + recN->vmtInfo->AddField(0, 0, fInfo.Scope, fInfo.Offset, fInfo.Case, fInfo.Name, fInfo.Type); + } + } + } + } + if (uses) delete[] uses; + } + } + } + } + StopProgress(); + + const int cntVmt = VmtList->Count; + stepMask = StartProgress(cntVmt, "Propagate VMT Names"); + for (int n = 0; n < cntVmt && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + PVmtListRec recV = (PVmtListRec)VmtList->Items[n]; + UpdateStatusBar(GetClsName(recV->vmtAdr)); + mainForm->PropagateVMTNames(recV->vmtAdr); + } + StopProgress(); +} +//--------------------------------------------------------------------------- +String __fastcall TAnalyzeThread::FindEvent(DWORD VmtAdr, String Name) +{ + DWORD adr = VmtAdr; + while (adr) + { + PInfoRec recN = GetInfoRec(adr); + if (recN && recN->vmtInfo->fields) + { + for (int n = 0; n < recN->vmtInfo->fields->Count; n++) + { + PFIELDINFO fInfo = (PFIELDINFO)recN->vmtInfo->fields->Items[n]; + if (SameText(fInfo->Name, Name)) return fInfo->Type; + } + } + adr = GetParentAdr(adr); + } + return ""; +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::FindPrototypes() +{ + int n, m, k, r, idx, usesNum; + PInfoRec recN; + String importName, _name; + MProcInfo aInfo; + MProcInfo *pInfo = &aInfo; + MTypeInfo atInfo; + MTypeInfo *tInfo = &atInfo; + WORD uses[128]; + + int stepMask = StartProgress(CodeSize, "Find Import Prototypes"); + + for (n = 0; n < CodeSize && !Terminated; n += 4) + { + if ((n & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfImport, n)) + { + recN = GetInfoRec(Pos2Adr(n)); + _name = recN->GetName(); + int dot = _name.Pos("."); + int len = _name.Length(); + bool found = false; + BYTE *p; WORD wlen; + //try find arguments + //FullName + importName = _name.SubString(dot + 1, len); + usesNum = KnowledgeBase.GetProcUses(importName.c_str(), uses); + for (m = 0; m < usesNum && !Terminated; m++) + { + idx = KnowledgeBase.GetProcIdx(uses[m], importName.c_str()); + if (idx != -1) + { + idx = KnowledgeBase.ProcOffsets[idx].NamId; + if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) + { + if (pInfo->MethodKind == 'F') + { + recN->kind = ikFunc; + recN->type = pInfo->TypeDef; + } + else if (pInfo->MethodKind == 'P') + { + recN->kind = ikProc; + } + if (!recN->procInfo) + recN->procInfo = new InfoProcInfo; + + if (pInfo->Args) + { + BYTE callKind = pInfo->CallKind; + + recN->procInfo->flags |= callKind; + + ARGINFO argInfo; p = pInfo->Args; int ss = 8; + for (k = 0; k < pInfo->ArgsNum; k++) + { + FillArgInfo(k, callKind, &argInfo, &p, &ss); + recN->procInfo->AddArg(&argInfo); + } + found = true; + } + } + if (found) break; + } + } + if (!found) + { + //try short name + importName = _name.SubString(dot + 1, len - dot - 1); + usesNum = KnowledgeBase.GetProcUses(importName.c_str(), uses); + for (m = 0; m < usesNum && !Terminated; m++) + { + idx = KnowledgeBase.GetProcIdx(uses[m], importName.c_str()); + if (idx != -1) + { + idx = KnowledgeBase.ProcOffsets[idx].NamId; + if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) + { + if (pInfo->MethodKind == 'F') + { + recN->kind = ikFunc; + recN->type = pInfo->TypeDef; + } + else if (pInfo->MethodKind == 'P') + { + recN->kind = ikProc; + } + if (!recN->procInfo) + recN->procInfo = new InfoProcInfo; + + if (pInfo->Args) + { + BYTE callKind = pInfo->CallKind; + recN->procInfo->flags |= callKind; + + ARGINFO argInfo; p = pInfo->Args; int ss = 8; + for (k = 0; k < pInfo->ArgsNum; k++) + { + FillArgInfo(k, callKind, &argInfo, &p, &ss); + recN->procInfo->AddArg(&argInfo); + } + found = true; + } + } + if (found) break; + } + } + } + if (!found) + { + //try without arguments + //FullName + importName = _name.SubString(dot + 1, len - dot); + usesNum = KnowledgeBase.GetProcUses(importName.c_str(), uses); + for (m = 0; m < usesNum && !Terminated; m++) + { + idx = KnowledgeBase.GetProcIdx(uses[m], importName.c_str()); + if (idx != -1) + { + idx = KnowledgeBase.ProcOffsets[idx].NamId; + if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) + { + if (pInfo->MethodKind == 'F') + { + recN->kind = ikFunc; + recN->type = pInfo->TypeDef; + } + else if (pInfo->MethodKind == 'P') + { + recN->kind = ikProc; + } + found = true; + } + if (found) break; + } + } + } + if (!found) + { + //try without arguments + //ShortName + importName = _name.SubString(dot + 1, len - dot - 1); + usesNum = KnowledgeBase.GetProcUses(importName.c_str(), uses); + for (m = 0; m < usesNum && !Terminated; m++) + { + idx = KnowledgeBase.GetProcIdx(uses[m], importName.c_str()); + if (idx != -1) + { + idx = KnowledgeBase.ProcOffsets[idx].NamId; + if (KnowledgeBase.GetProcInfo(idx, INFO_ARGS, pInfo)) + { + if (pInfo->MethodKind == 'F') + { + recN->kind = ikFunc; + recN->type = pInfo->TypeDef; + } + else if (pInfo->MethodKind == 'P') + { + recN->kind = ikProc; + } + found = true; + } + if (found) break; + } + } + } + } + } + StopProgress(); + + StartProgress(ResInfo->FormList->Count, "Find Event Prototypes"); + + for (n = 0; n < ResInfo->FormList->Count && !Terminated; n++) + { + UpdateProgress(); + TDfm* dfm = (TDfm*)ResInfo->FormList->Items[n]; + String className = dfm->ClassName; + DWORD formAdr = GetClassAdr(className); + if (!formAdr) continue; + recN = GetInfoRec(formAdr); + if (!recN || !recN->vmtInfo->methods) continue; + + //The first: form events + TList* ev = dfm->Events; + for (m = 0; m < ev->Count && !Terminated; m++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[m]; + DWORD controlAdr = GetClassAdr(dfm->ClassName); + String typeName = FindEvent(controlAdr, "F" + eInfo->EventName); + if (typeName == "") typeName = FindEvent(controlAdr, eInfo->EventName); + if (typeName != "") + { + for (k = 0; k < recN->vmtInfo->methods->Count && !Terminated; k++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[k]; + if (SameText(recM->name, className + "." + eInfo->ProcName)) + { + PInfoRec recN1 = GetInfoRec(recM->address); + if (recN1) + { + String clsname = className; + while (1) + { + if (KnowledgeBase.GetKBPropertyInfo(clsname, eInfo->EventName, tInfo)) + { + recN1->kind = ikProc; + recN1->procInfo->flags |= PF_EVENT; + recN1->procInfo->DeleteArgs(); + //eax always Self + recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); + //transform declaration to arguments + recN1->procInfo->AddArgsFromDeclaration(tInfo->Decl.c_str(), 1, 0); + break; + } + clsname = GetParentName(clsname); + if (clsname == "") break; + } + } + else + { + ShowMessage("recN is Null"); + } + break; + } + } + } + } + //The second: components events + for (m = 0; m < dfm->Components->Count && !Terminated; m++) + { + PComponentInfo cInfo = (PComponentInfo)dfm->Components->Items[m]; + TList* ev = cInfo->Events; + for (k = 0; k < ev->Count && !Terminated; k++) + { + PEventInfo eInfo = (PEventInfo)ev->Items[k]; + DWORD controlAdr = GetClassAdr(cInfo->ClassName); + String typeName = FindEvent(controlAdr, "F" + eInfo->EventName); + if (typeName == "") typeName = FindEvent(controlAdr, eInfo->EventName); + if (typeName != "") + { + for (r = 0; r < recN->vmtInfo->methods->Count && !Terminated; r++) + { + PMethodRec recM = (PMethodRec)recN->vmtInfo->methods->Items[r]; + if (SameText(recM->name, className + "." + eInfo->ProcName)) + { + PInfoRec recN1 = GetInfoRec(recM->address); + if (recN1) + { + String clsname = className; + while (1) + { + if (KnowledgeBase.GetKBPropertyInfo(clsname, eInfo->EventName, tInfo)) + { + recN1->kind = ikProc; + recN1->procInfo->flags |= PF_EVENT; + recN1->procInfo->DeleteArgs(); + //eax always Self + recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); + //transform declaration to arguments + recN1->procInfo->AddArgsFromDeclaration(tInfo->Decl.c_str(), 1, 0); + break; + } + clsname = GetParentName(clsname); + if (clsname == "") break; + } + } + else + { + ShowMessage("recN is Null"); + } + break; + } + } + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +typedef struct +{ + bool used; + char *name; //èìÿ þíèòà + float matched; //ìàêñèìàëüíîå êîë-âî ñîâïàäåíèé + int maxno; //íîìåð þíèòà ñ ìàêñèìàëüíûì êîë-âîì ñîâïàäåíèé +} StdUnitInfo, *PStdUnitInfo; + +#define StdUnitsNum 7 +StdUnitInfo StdUnits[] = { +{false, "Types", 0.0, -1}, +{false, "Multimon", 0.0, -1}, +{false, "VarUtils", 0.0, -1}, +{false, "StrUtils", 0.0, -1}, +{false, "Registry", 0.0, -1}, +{false, "IniFiles", 0.0, -1}, +{false, "Clipbrd", 0.0, -1}, +{false, 0, 0.0, -1} +}; +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::ScanCode() +{ + bool matched; + WORD moduleID; + DWORD Adr, iniAdr, finAdr, vmtAdr; + int FirstProcIdx, LastProcIdx, Num, DumpSize; + int i, n, m, k, r, u, Idx, fromPos, toPos, stepMask; + PUnitRec recU; + PInfoRec recN; + MProcInfo aInfo; + MProcInfo *pInfo = &aInfo; + MConstInfo acInfo; + MConstInfo *cInfo = &acInfo; + String className, unitName; + + StartProgress(UnitsNum, "Scan Initialization and Finalization procs"); + + //Begin with initialization and finalization procs + for (n = 0; n < UnitsNum && !Terminated; n++) + { + UpdateProgress(); + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + iniAdr = recU->iniadr; + if (iniAdr && !recU->trivialIni) + { + mainForm->AnalyzeProc(0, iniAdr); + + for (u = 0; u < recU->names->Count && !Terminated; u++) + { + moduleID = KnowledgeBase.GetModuleID(recU->names->Strings[u].c_str()); + if (moduleID == 0xFFFF) continue; + + recU->kb = true; + //If unit is in knowledge base try to find proc Initialization + Idx = KnowledgeBase.GetProcIdx(moduleID, recU->names->Strings[u].c_str()); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + matched = (MatchCode(Code + Adr2Pos(iniAdr), pInfo) && mainForm->StrapCheck(Adr2Pos(iniAdr), pInfo)); + if (matched) mainForm->StrapProc(Adr2Pos(iniAdr), Idx, pInfo, true, pInfo->DumpSz); + } + } + } + } + } + finAdr = recU->finadr; + if (finAdr && !recU->trivialFin) + { + mainForm->AnalyzeProc(0, finAdr); + + for (u = 0; u < recU->names->Count && !Terminated; u++) + { + moduleID = KnowledgeBase.GetModuleID(recU->names->Strings[u].c_str()); + if (moduleID == 0xFFFF) continue; + + recU->kb = true; + //If unit is in knowledge base try to find proc Finalization + Idx = KnowledgeBase.GetProcIdx(moduleID, "Finalization"); + if (Idx != -1) + { + Idx = KnowledgeBase.ProcOffsets[Idx].NamId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + matched = (MatchCode(Code + Adr2Pos(finAdr), pInfo) && mainForm->StrapCheck(Adr2Pos(finAdr), pInfo)); + if (matched) mainForm->StrapProc(Adr2Pos(finAdr), Idx, pInfo, true, pInfo->DumpSz); + } + } + } + } + } + } + StopProgress(); + //EP + mainForm->AnalyzeProc(0, EP); + //Classes (methods, dynamics procedures, virtual methods) + stepMask = StartProgress(TotalSize, "Analyze Class Tables"); + for (n = 0; n < TotalSize && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->kind == ikVMT) + { + vmtAdr = Pos2Adr(n); + UpdateStatusBar(GetClsName(vmtAdr)); + + mainForm->AnalyzeMethodTable(0, vmtAdr, &Terminated); + if (Terminated) break; + mainForm->AnalyzeDynamicTable(0, vmtAdr, &Terminated); + if (Terminated) break; + mainForm->AnalyzeVirtualTable(0, vmtAdr, &Terminated); + } + } + StopProgress(); + //Scan some standard units + StartProgress(StdUnitsNum, "Scan Standard Units: step1"); + for (r = 0; !Terminated; r++) + { + UpdateProgress(); + if (!StdUnits[r].name) break; + StdUnits[r].used = false; + StdUnits[r].matched = 0.0; + StdUnits[r].maxno = -1; + moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); + if (moduleID == 0xFFFF) continue; + + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) continue; + + for (n = 0; n < UnitsNum && !Terminated; n++) + { + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + //Analyze units without name + if (!recU->names->Count) + { + recU->matchedPercent = 0.0; + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + for (m = fromPos; m < toPos && !Terminated; m++) + { + if (IsFlagSet(cfProcStart, m)) + { + if (r != 5 && Pos2Adr(m) == recU->iniadr) continue; + if (r != 5 && Pos2Adr(m) == recU->finadr) continue; + + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + matched = false; + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) + { + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + //If method of class, check that ClassName is found + //className = ExtractClassName(pInfo->ProcName); + //if (className == "" || GetOwnTypeByName(className)) + //{ + recU->matchedPercent += 100.0*pInfo->DumpSz/(toPos - fromPos + 1); + break; + //} + } + } + } + } + } + } + //float matchedPercent = 100.0*recU->matchedSize/(toPos - fromPos + 1); + if (recU->matchedPercent > StdUnits[r].matched) + { + StdUnits[r].matched = recU->matchedPercent; + StdUnits[r].maxno = n; + } + } + } + } + StopProgress(); + StartProgress(StdUnitsNum, "Scan Standard Units: step2"); + for (r = 0; !Terminated; r++) + { + UpdateProgress(); + if (!StdUnits[r].name) break; + if (StdUnits[r].used) continue; + if (StdUnits[r].matched < 50.0) continue; + + moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); + if (moduleID == 0xFFFF) continue; + + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) continue; + + n = StdUnits[r].maxno; + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + //Analyze units without name + if (!recU->names->Count) + { + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + for (m = fromPos; m < toPos && !Terminated; m++) + { + if (IsFlagSet(cfProcStart, m)) + { + if (r != 5 && Pos2Adr(m) == recU->iniadr) continue; + if (r != 5 && Pos2Adr(m) == recU->finadr) continue; + + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + matched = false; + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) + { + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + //If method of class, check that ClassName is found + //className = ExtractClassName(pInfo->ProcName); + //if (className == "" || GetOwnTypeByName(className)) + //{ + mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); + StdUnits[r].used = true; + break; + //} + } + } + } + } + } + } + } + } + StopProgress(); + for (n = 0; n < UnitsNum && !Terminated; n++) + { + //UpdateProgress(); + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + //Delphi2 - it is possible that toPos = -1 + if (toPos == -1) toPos = TotalSize; + + for (u = 0; u < recU->names->Count && !Terminated; u++) + { + unitName = recU->names->Strings[u]; + moduleID = KnowledgeBase.GetModuleID(unitName.c_str()); + if (moduleID == 0xFFFF) continue; + + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx, &DumpSize)) continue; + + stepMask = StartProgress(toPos - fromPos + 1, "Scan Unit " + unitName + ": step1"); + + recU->kb = true; + for (m = fromPos, i = 0; m < toPos && !Terminated; m++, i++) + { + if ((i & stepMask) == 0) UpdateProgress(); + + if (!*(Code + m)) continue; + if (IsFlagSet(cfProcStart, m) || !Flags[m]) + { + if (Pos2Adr(m) == recU->iniadr && recU->trivialIni) continue; + if (Pos2Adr(m) == recU->finadr && recU->trivialFin) continue; + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) + { + //Check code matching + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + //If method of class, check that ClassName is found + //className = ExtractClassName(pInfo->ProcName); + //if (className == "" || GetOwnTypeByName(className)) + //{ + mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); + m += pInfo->DumpSz - 1; + break; + //} + } + } + } + } + } + } + StopProgress(); + } + } + //Òåïåðü ïîïðîáóåì îïÿòü ïðîéòèñü ïî VMT è ïîèñêàòü èõ â áàçå çíàíèé + stepMask = StartProgress(TotalSize, "Scan Units: step 2"); + for (n = 0; n < TotalSize && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->kind == ikVMT) + { + String ConstName = "_DV_" + recN->GetName(); + Num = KnowledgeBase.GetConstIdxs(ConstName.c_str(), &Idx); + if (Num == 1) + { + Adr = Pos2Adr(n); + recU = mainForm->GetUnit(Adr); + if (!recU || recU->trivial) continue; + + if (!recU->names->Count) + { + Idx = KnowledgeBase.ConstOffsets[Idx].NamId; + if (KnowledgeBase.GetConstInfo(Idx, INFO_DUMP, cInfo)) + { + moduleID = cInfo->ModuleID; + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) continue; + + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + for (m = fromPos; m < toPos && !Terminated; m++) + { + if (IsFlagSet(cfProcStart, m)) + { + if (Pos2Adr(m) == recU->iniadr && recU->trivialIni) continue; + if (Pos2Adr(m) == recU->finadr && recU->trivialFin) continue; + + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + matched = false; + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo)) + { + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + String unitName = KnowledgeBase.GetModuleName(moduleID); + FMain_11011981->SetUnitName(recU, unitName); + recU->kb = true; + mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); + break; + } + } + } + } + } + } + } + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::ScanCode1() +{ + bool matched; + WORD moduleID; + DWORD pos, Adr; + int FirstProcIdx, LastProcIdx, Num; + int n, m, k, r, u, Idx, fromPos, toPos; + PUnitRec recU; + PInfoRec recN; + MProcInfo aInfo; + MProcInfo *pInfo = &aInfo; + String className; + + StartProgress(UnitsNum, "Scan Code more..."); + for (n = 0; n < UnitsNum && !Terminated; n++) + { + UpdateProgress(); + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + + for (u = 0; u < recU->names->Count && !Terminated; u++) + { + moduleID = KnowledgeBase.GetModuleID(recU->names->Strings[u].c_str()); + if (moduleID == 0xFFFF) continue; + + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) continue; + for (m = fromPos; m < toPos && !Terminated; m++) + { + if (IsFlagSet(cfProcStart, m)) + { + if (Pos2Adr(m) == recU->iniadr && recU->trivialIni) continue; + if (Pos2Adr(m) == recU->finadr && recU->trivialFin) continue; + + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) + { + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + //If method of class, check that ClassName is found + //className = ExtractClassName(pInfo->ProcName); + //if (className == "" || GetOwnTypeByName(className)) + //{ + mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); + break; + //} + } + } + } + } + } + } + } + } + StopProgress(); + StartProgress(StdUnitsNum, "Scan Standard Units more: step1"); + //Ïîïðîáóåì íåêîòîðûå ñòàíäàðòíûå þíèòû + for (r = 0; !Terminated; r++) + { + UpdateProgress(); + if (!StdUnits[r].name) break; + if (StdUnits[r].used) continue; + StdUnits[r].matched = 0; + StdUnits[r].maxno = -1; + moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); + if (moduleID == 0xFFFF) continue; + + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) continue; + + for (n = 0; n < UnitsNum && !Terminated; n++) + { + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + //Àíàëèçèðóåì íåïîèìåíîâàííûå þíèòû + if (!recU->names->Count) + { + recU->matchedPercent = 0.0; + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + for (m = fromPos; m < toPos && !Terminated; m++) + { + if (IsFlagSet(cfProcStart, m)) + { + if (Pos2Adr(m) == recU->iniadr) continue; + if (Pos2Adr(m) == recU->finadr) continue; + + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + matched = false; + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) + { + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + //If method of class, check that ClassName is found + //className = ExtractClassName(pInfo->ProcName); + //if (className == "" || GetOwnTypeByName(className)) + //{ + recU->matchedPercent += 100.0*pInfo->DumpSz/(toPos - fromPos + 1); + break; + //} + } + } + } + } + } + } + //float matchedPercent = 100.0*recU->matchedSize/(toPos - fromPos + 1); + if (recU->matchedPercent > StdUnits[r].matched) + { + StdUnits[r].matched = recU->matchedPercent; + StdUnits[r].maxno = n; + } + } + } + } + StopProgress(); + StartProgress(StdUnitsNum, "Scan Standard Units more: step2"); + for (r = 0; !Terminated; r++) + { + UpdateProgress(); + if (!StdUnits[r].name) break; + if (StdUnits[r].used) continue; + if (StdUnits[r].matched < 50.0) continue; + + moduleID = KnowledgeBase.GetModuleID(StdUnits[r].name); + if (moduleID == 0xFFFF) continue; + + if (!KnowledgeBase.GetProcIdxs(moduleID, &FirstProcIdx, &LastProcIdx)) continue; + + n = StdUnits[r].maxno; + recU = (UnitRec*)Units->Items[n]; + if (recU->trivial) continue; + + //Àíàëèçèðóåì íåïîèìåíîâàííûå þíèòû + if (!recU->names->Count) + { + fromPos = Adr2Pos(recU->fromAdr); + toPos = Adr2Pos(recU->toAdr); + for (m = fromPos; m < toPos && !Terminated; m++) + { + if (IsFlagSet(cfProcStart, m)) + { + if (Pos2Adr(m) == recU->iniadr) continue; + if (Pos2Adr(m) == recU->finadr) continue; + + recN = GetInfoRec(Pos2Adr(m)); + if (recN && recN->HasName()) continue; + UpdateAddrInStatusBar(Pos2Adr(m)); + for (k = FirstProcIdx; k <= LastProcIdx && !Terminated; k++) + { + Idx = KnowledgeBase.ProcOffsets[k].ModId; + if (!KnowledgeBase.IsUsedProc(Idx)) + { + matched = false; + if (KnowledgeBase.GetProcInfo(Idx, INFO_DUMP | INFO_ARGS, pInfo) && pInfo->DumpSz >= 8 && m + pInfo->DumpSz < toPos) + { + matched = (MatchCode(Code + m, pInfo) && mainForm->StrapCheck(m, pInfo)); + if (matched) + { + //If method of class, check that ClassName is found + //className = ExtractClassName(pInfo->ProcName); + //if (className == "" || GetOwnTypeByName(className)) + //{ + mainForm->StrapProc(m, Idx, pInfo, true, pInfo->DumpSz); + StdUnits[r].used = true; + break; + //} + } + } + } + } + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::ScanVMTs() +{ + int stepMask = StartProgress(TotalSize, "Scan Virtual Method Tables"); + for (int n = 0; n < TotalSize && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->kind == ikVMT) + { + DWORD vmtAdr = Pos2Adr(n); + String name = recN->GetName(); + UpdateStatusBar(name); + + mainForm->ScanFieldTable(vmtAdr); + if (Terminated) break; + mainForm->ScanMethodTable(vmtAdr, name); + if (Terminated) break; + mainForm->ScanVirtualTable(vmtAdr); + if (Terminated) break; + mainForm->ScanDynamicTable(vmtAdr); + if (Terminated) break; + + if (DelphiVersion != 2) + { + mainForm->ScanIntfTable(vmtAdr); + mainForm->ScanAutoTable(vmtAdr); + if (Terminated) break; + } + + mainForm->ScanInitTable(vmtAdr); + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::ScanConsts() +{ + WORD ModID; + int n, m, u, Bytes, ResStrIdx, pos, ResStrNum, ResStrNo; + DWORD adr, resid; + PUnitRec recU; + PInfoRec recN; + MResStrInfo arsInfo; + MResStrInfo *rsInfo = &arsInfo; + String uname; + char buf[1024]; + + if (Terminated) return; + if (HInstanceVarAdr == 0xFFFFFFFF) return; + + HINSTANCE hInst = LoadLibraryEx(mainForm->SourceFile.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);//DONT_RESOLVE_DLL_REFERENCES); + if (!hInst) return; + + //Array of counters for units frequences + int *Counters = new int[KnowledgeBase.ModuleCount]; + + StartProgress(UnitsNum, "Scan Resource Strings"); + for (m = 0; m < UnitsNum && !Terminated; m++) + { + UpdateProgress(); + recU = (PUnitRec)Units->Items[m]; + if (!recU) continue; + + ModID = 0xFFFF; + //If module from KB load information about ResStrings + if (recU->names->Count) + { + for (u = 0; u < recU->names->Count && !Terminated; u++) + { + UpdateAddrInStatusBar(u); + ModID = KnowledgeBase.GetModuleID(recU->names->Strings[u].c_str()); + //Åñëè èç áàçû çíàíèé, âûòàùèì èç íåå èíôîðìàöèþ î ResStr + if (ModID != 0xFFFF) + { + for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) + { + adr = *((DWORD*)(Code + n)); + resid = *((DWORD*)(Code + n + 4)); + + if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) + { + recN = GetInfoRec(Pos2Adr(n)); + //If export at this position, delete InfoRec and create new (ikResString) + if (IsFlagSet(cfExport, n)) + { + ClearFlag(cfProcStart, n); + delete recN; + recN = 0; + } + if (!recN) + recN = new InfoRec(n, ikResString); + else + { + if (recN->kind == ikResString) continue; + //may be ikData + if (!recN->rsInfo) recN->rsInfo = new InfoResStringInfo; + } + recN->type = "TResStringRec"; + + //Set Flags + SetFlags(cfData, n, 8); + //Get Context + Bytes = LoadString(hInst, (UINT)resid, buf, 1024); + recN->rsInfo->value = String(buf, Bytes); + + ResStrIdx = KnowledgeBase.GetResStrIdx(ModID, buf); + if (ResStrIdx != -1) + { + ResStrIdx = KnowledgeBase.ResStrOffsets[ResStrIdx].NamId; + if (KnowledgeBase.GetResStrInfo(ResStrIdx, 0, rsInfo)) + { + if (!recN->HasName()) + { + UpdateStatusBar(rsInfo->ResStrName); + recN->SetName(rsInfo->ResStrName); + } + } + } + else + { + if (!recN->HasName()) + { + recN->ConcatName("SResString" + String(LastResStrNo)); + LastResStrNo++; + } + } + } + } + } + //Else extract ResStrings from analyzed file + else + { + for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) + { + adr = *((DWORD*)(Code + n)); + resid = *((DWORD*)(Code + n + 4)); + + if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) + { + recN = GetInfoRec(Pos2Adr(n)); + //If export at this position, delete InfoRec and create new (ikResString) + if (IsFlagSet(cfExport, n)) + { + ClearFlag(cfProcStart, n); + delete recN; + recN = 0; + } + if (!recN) + recN = new InfoRec(n, ikResString); + else + { + if (recN->kind == ikResString) continue; + //may be ikData + if (!recN->rsInfo) recN->rsInfo = new InfoResStringInfo; + } + recN->type = "TResStringRec"; + + //Set Flags + SetFlags(cfData, n, 8); + //Get Context + Bytes = LoadString(hInst, (UINT)resid, buf, 1024); + recN->rsInfo->value = String(buf, Bytes); + + if (!recN->HasName()) + { + recN->ConcatName("SResString" + String(LastResStrNo)); + LastResStrNo++; + } + } + } + } + } + } + //If unit has no name check it is module of ResStrings + else + { + UpdateProgress(); + memset(Counters, 0, KnowledgeBase.ModuleCount*sizeof(int)); + ResStrNum = 0; + + for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) + { + adr = *((DWORD*)(Code + n)); + resid = *((DWORD*)(Code + n + 4)); + + if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) + { + Bytes = LoadString(hInst, (UINT)resid, buf, 1024); + //Number of ReStrings in this module + ResStrNum++; + for (ResStrNo = 0; !Terminated; ) + { + ResStrIdx = KnowledgeBase.GetResStrIdx(ResStrNo, buf); + if (ResStrIdx == -1) break; + ResStrNo = ResStrIdx + 1; + ResStrIdx = KnowledgeBase.ResStrOffsets[ResStrIdx].NamId; + if (KnowledgeBase.GetResStrInfo(ResStrIdx, 0, rsInfo)) + { + Counters[rsInfo->ModuleID]++; + } + } + } + } + //What module has frequency >= ResStrNum + if (ResStrNum) + { + for (n = 0; n < KnowledgeBase.ModuleCount && !Terminated; n++) + { + if (Counters[n] >= 0.9*ResStrNum) + { + ModID = n; + break; + } + } + //Module is found + if (ModID != 0xFFFF) + { + uname = KnowledgeBase.GetModuleName(ModID); + FMain_11011981->SetUnitName(recU, uname); + recU->kb = true; + + for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) + { + adr = *((DWORD*)(Code + n)); + resid = *((DWORD*)(Code + n + 4)); + + if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) + { + recN = GetInfoRec(Pos2Adr(n)); + //If export at this position, delete InfoRec and create new (ikResString) + if (IsFlagSet(cfExport, n)) + { + ClearFlag(cfProcStart, n); + delete recN; + recN = 0; + } + if (!recN) + recN = new InfoRec(n, ikResString); + else + { + if (recN->kind == ikResString) continue; + //may be ikData + if (!recN->rsInfo) recN->rsInfo = new InfoResStringInfo; + } + recN->type = "TResStringRec"; + + //Set Flags + SetFlags(cfData, n, 8); + //Get Context + Bytes = LoadString(hInst, (UINT)resid, buf, 1024); + recN->rsInfo->value = String(buf, Bytes); + + ResStrIdx = KnowledgeBase.GetResStrIdx(ModID, buf); + if (ResStrIdx != -1) + { + ResStrIdx = KnowledgeBase.ResStrOffsets[ResStrIdx].NamId; + if (KnowledgeBase.GetResStrInfo(ResStrIdx, 0, rsInfo)) + { + if (!recN->HasName()) + { + UpdateStatusBar(rsInfo->ResStrName); + recN->SetName(rsInfo->ResStrName); + } + } + } + else + { + if (!recN->HasName()) + { + recN->ConcatName("SResString" + String(LastResStrNo)); + LastResStrNo++; + } + } + } + } + } + //Module not found, get ResStrings from analyzed file + else + { + for (n = Adr2Pos(recU->fromAdr); (n < Adr2Pos(recU->toAdr)) && !Terminated; n += 4) + { + adr = *((DWORD*)(Code + n)); + resid = *((DWORD*)(Code + n + 4)); + + if (IsValidImageAdr(adr) && adr == HInstanceVarAdr && resid < 0x10000) + { + recN = GetInfoRec(Pos2Adr(n)); + //If export at this position, delete InfoRec and create new (ikResString) + if (IsFlagSet(cfExport, n)) + { + ClearFlag(cfProcStart, n); + delete recN; + recN = 0; + } + if (!recN) + recN = new InfoRec(n, ikResString); + else + { + if (recN->kind == ikResString) continue; + //may be ikData + if (!recN->rsInfo) recN->rsInfo = new InfoResStringInfo; + } + recN->type = "TResStringRec"; + + //Set Flags + SetFlags(cfData, n, 8); + //Get Context + Bytes = LoadString(hInst, (UINT)resid, buf, 1024); + recN->rsInfo->value = String(buf, Bytes); + + if (!recN->HasName()) + { + recN->ConcatName("SResString" + String(LastResStrNo)); + LastResStrNo++; + } + } + } + } + } + } + } + FreeLibrary(hInst); + StopProgress(); + delete[] Counters; +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::ScanGetSetStoredProcs() +{ + for (int m = 0; m < OwnTypeList->Count && !Terminated; m++) + { + PTypeRec recT = (PTypeRec)OwnTypeList->Items[m]; + if (recT->kind == ikClass) + { + int n = Adr2Pos(recT->adr); + //SelfPtr + n += 4; + //typeKind + n++; + BYTE len = Code[n]; n++; + //clsName + n += len; + + DWORD classVMT = *((DWORD*)(Code + n)); n += 4; + PInfoRec recN1 = GetInfoRec(classVMT + cVmtSelfPtr); + /*DWORD parentAdr = *((DWORD*)(Code + n));*/ n += 4; + WORD propCount = *((WORD*)(Code + n)); n += 2; + //Skip unit name + len = Code[n]; n++; + n += len; + //Real properties count + propCount = *((WORD*)(Code + n)); n += 2; + + for (int i = 0; i < propCount && !Terminated; i++) + { + DWORD propType = *((DWORD*)(Code + n)); n += 4; + int posn = Adr2Pos(propType); + posn += 4; + posn++; //property type + len = Code[posn]; posn++; + String fieldType = String((char*)(Code + posn), len); + + DWORD getProc = *((DWORD*)(Code + n)); n += 4; + DWORD setProc = *((DWORD*)(Code + n)); n += 4; + DWORD storedProc = *((DWORD*)(Code + n)); n += 4; + //idx + n += 4; + //defval + n += 4; + //nameIdx + n += 2; + len = Code[n]; n++; + String fieldName = String((char*)(Code + n), len); n += len; + + int fieldOfs = -1; + if ((getProc & 0xFFFFFF00)) + { + if ((getProc & 0xFF000000) == 0xFF000000) + fieldOfs = getProc & 0x00FFFFFF; + } + if ((setProc & 0xFFFFFF00)) + { + if ((setProc & 0xFF000000) == 0xFF000000) + fieldOfs = setProc & 0x00FFFFFF; + } + if ((storedProc & 0xFFFFFF00)) + { + if ((storedProc & 0xFF000000) == 0xFF000000) + fieldOfs = storedProc & 0x00FFFFFF; + } + if (recN1 && fieldOfs != -1) recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, fieldName, fieldType); + } + } + } +} +//--------------------------------------------------------------------------- +//LString +//RefCnt Length Data +//0 4 8 +// recN (kind = ikLString, name = context) +//UString +//CodePage Word RefCnt Length Data +//0 2 4 8 12 +// recN (kind = ikUString, name = context) +void __fastcall TAnalyzeThread::FindStrings() +{ + int i, len; + WORD codePage, elemSize; + DWORD refCnt; + PInfoRec recN; + + if (DelphiVersion >= 2009) + { + int stepMask = StartProgress(CodeSize, "Scan UStrings"); + //Scan UStrings + for (i = 0; i < CodeSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfData, i)) continue; + + codePage = *((WORD*)(Code + i)); + elemSize = *((WORD*)(Code + i + 2)); + if (!elemSize || elemSize > 4) continue; + refCnt = *((DWORD*)(Code + i + 4)); + if (refCnt != 0xFFFFFFFF) continue; + //len = wcslen((wchar_t*)(Code + i + 12)); + len = *((int*)(Code + i + 8)); + if (len <= 0 || len > 10000) continue; + if (i + 12 + (len + 1)*elemSize >= CodeSize) continue; + if (!Infos[i + 12]) + { + UpdateAddrInStatusBar(Pos2Adr(i)); + recN = new InfoRec(i + 12, ikUString); + if (elemSize == 1) + recN->SetName(TransformString(Code + i + 12, len)); + else + recN->SetName(TransformUString(codePage, (wchar_t*)(Code + i + 12), len)); + } + //Align to 4 bytes + len = (12 + (len + 1)*elemSize + 3) & (-4); + SetFlags(cfData, i, len); + } + StopProgress(); + } + + int stepMask = StartProgress(CodeSize, "Scan LStrings"); + //Scan LStrings + for (i = 0; i < CodeSize && !Terminated; i += 4) + { + if ((i & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfData, i)) continue; + + refCnt = *((DWORD*)(Code + i)); + if (refCnt != 0xFFFFFFFF) continue; + len = *((int*)(Code + i + 4)); + if (len <= 0 || len > 10000) continue; + if (i + 8 + len + 1 >= CodeSize) continue; + //Check last 0 + if (*(Code + i + 8 + len)) continue; + //Check flags + //!!! + if (!Infos[i + 8]) + { + UpdateAddrInStatusBar(Pos2Adr(i)); + recN = new InfoRec(i + 8, ikLString); + recN->SetName(TransformString(Code + i + 8, len)); + } + //Align to 4 bytes + len = (8 + len + 1 + 3) & (-4); + SetFlags(cfData, i, len); + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::AnalyzeCode1() +{ + String msg = "Analyzing step 1..."; + PUnitRec recU; + + StartProgress(UnitsNum, msg); + + //Initialization and Finalization procedures + for (int n = 0; n < UnitsNum && !Terminated; n++) + { + UpdateProgress(); + recU = (UnitRec*)Units->Items[n]; + if (recU) + { + DWORD iniAdr = recU->iniadr; + if (iniAdr) + { + UpdateStatusBar(iniAdr); + mainForm->AnalyzeProc(1, iniAdr); + } + DWORD finAdr = recU->finadr; + if (finAdr) + { + UpdateStatusBar(finAdr); + mainForm->AnalyzeProc(1, finAdr); + } + } + } + StopProgress(); + int stepMask = StartProgress(TotalSize, msg); + //EP + mainForm->AnalyzeProc(1, EP); + DWORD vmtAdr; + //Classes (methods, dynamics procedures, virtual methods) + for (int n = 0; n < TotalSize && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + PInfoRec recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->kind == ikVMT) + { + vmtAdr = Pos2Adr(n); + UpdateAddrInStatusBar(vmtAdr); + + mainForm->AnalyzeMethodTable(1, vmtAdr, &Terminated); + if (Terminated) break; + mainForm->AnalyzeDynamicTable(1, vmtAdr, &Terminated); + if (Terminated) break; + mainForm->AnalyzeVirtualTable(1, vmtAdr, &Terminated); + } + } + StopProgress(); + //All procs + stepMask = StartProgress(CodeSize, msg); + for (int n = 0; n < CodeSize && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfProcStart, n)) + { + DWORD adr = Pos2Adr(n); + UpdateAddrInStatusBar(adr); + mainForm->AnalyzeProc(1, adr); + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::AnalyzeCode2(bool args) +{ + PUnitRec recU; + + int stepMask = StartProgress(CodeSize, "Analyzing step 2..."); + + //EP + mainForm->AnalyzeProc(2, EP); + + for (int n = 0; n < CodeSize && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + if (IsFlagSet(cfProcStart, n)) + { + DWORD adr = Pos2Adr(n); + UpdateAddrInStatusBar(adr); + if (args) mainForm->AnalyzeArguments(adr); + mainForm->AnalyzeProc(2, adr); + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::PropagateClassProps() +{ + PInfoRec recN, recN1; + + int stepMask = StartProgress(CodeSize, "Propagating Class Properties..."); + for (int n = 0; n < CodeSize && !Terminated; n += 4) + { + if ((n & stepMask) == 0) UpdateProgress(); + recN = GetInfoRec(Pos2Adr(n)); + if (recN && recN->HasName()) + { + BYTE typeKind = recN->kind; + if (typeKind > ikProcedure) continue; + //Ïðîéäåìñÿ ïî ñâîéñòâàì êëàññà è ïîèìåíóåì ïðîöåäóðû + if (typeKind == ikClass) + { + int pos = n; + //SelfPointer + pos += 4; + //TypeKind + pos++; + BYTE len = Code[pos]; pos++; + String clsName = String((char*)(Code + pos), len); pos += len; + DWORD classVMT = *((DWORD*)(Code + pos)); pos += 4; + pos += 4; //ParentAdr + pos += 2; //PropCount + //UnitName + len = Code[pos]; pos++; + pos += len; + WORD propCount = *((WORD*)(Code + pos)); pos += 2; + + for (int i = 0; i < propCount && !Terminated; i++) + { + DWORD propType = *((DWORD*)(Code + pos)); pos += 4; + int posn = Adr2Pos(propType); posn += 4; + posn++; //property type + len = Code[posn]; posn++; + String typeName = String((char*)(Code + posn), len); + + DWORD getProc = *((DWORD*)(Code + pos)); pos += 4; + DWORD setProc = *((DWORD*)(Code + pos)); pos += 4; + DWORD storedProc = *((DWORD*)(Code + pos)); pos += 4; + pos += 4; //Idx + pos += 4; //DefVal + pos += 2; //NameIdx + len = Code[pos]; pos++; + String name = String((char*)(Code + pos), len); pos += len; + + int vmtofs, fieldOfs; + PFIELDINFO fInfo; + + if ((getProc & 0xFFFFFF00)) + { + if ((getProc & 0xFF000000) == 0xFF000000) + { + fieldOfs = getProc & 0x00FFFFFF; + recN1 = GetInfoRec(classVMT + cVmtSelfPtr); + if (recN1 && recN1->vmtInfo) + recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, name, typeName); + } + else if ((getProc & 0xFF000000) == 0xFE000000) + { + if ((getProc & 0x00008000)) + vmtofs = -((int)getProc & 0x0000FFFF); + else + vmtofs = getProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + getProc = *((DWORD*)(Code + posn)); + recN1 = GetInfoRec(getProc); + if (!recN1) + recN1 = new InfoRec(Adr2Pos(getProc), ikFunc); + else if (!recN1->procInfo) + recN1->procInfo = new InfoProcInfo; + + recN1->kind = ikFunc; + recN1->type = typeName; + if (!recN1->HasName()) + recN1->SetName(clsName + ".Get" + name); + recN1->procInfo->flags |= PF_METHOD; + recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + mainForm->AnalyzeProc1(getProc, 0, 0, 0, false); + } + else + { + recN1 = GetInfoRec(getProc); + if (!recN1) + recN1 = new InfoRec(Adr2Pos(getProc), ikFunc); + else if (!recN1->procInfo) + recN1->procInfo = new InfoProcInfo; + recN1->kind = ikFunc; + if (!recN1->HasName()) + recN1->SetName(clsName + ".Get" + name); + recN1->procInfo->flags |= PF_METHOD; + recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + mainForm->AnalyzeProc1(getProc, 0, 0, 0, false); + } + } + if ((setProc & 0xFFFFFF00)) + { + if ((setProc & 0xFF000000) == 0xFF000000) + { + fieldOfs = setProc & 0x00FFFFFF; + recN1 = GetInfoRec(classVMT + cVmtSelfPtr); + if (recN1 && recN1->vmtInfo) + recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, name, typeName); + } + else if ((setProc & 0xFF000000) == 0xFE000000) + { + if ((setProc & 0x00008000)) + vmtofs = -((int)setProc & 0x0000FFFF); + else + vmtofs = setProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + setProc = *((DWORD*)(Code + posn)); + recN1 = GetInfoRec(setProc); + if (!recN1) + recN1 = new InfoRec(Adr2Pos(setProc), ikProc); + else if (!recN1->procInfo) + recN1->procInfo = new InfoProcInfo; + recN1->kind = ikProc; + if (!recN1->HasName()) + recN1->SetName(clsName + ".Set" + name); + recN1->procInfo->flags |= PF_METHOD; + recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); + mainForm->AnalyzeProc1(setProc, 0, 0, 0, false); + } + else + { + recN1 = GetInfoRec(setProc); + if (!recN1) + recN1 = new InfoRec(Adr2Pos(setProc), ikProc); + else if (!recN1->procInfo) + recN1->procInfo = new InfoProcInfo; + recN1->kind = ikProc; + if (!recN1->HasName()) + recN1->SetName(clsName + ".Set" + name); + recN1->procInfo->flags |= PF_METHOD; + recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); + mainForm->AnalyzeProc1(setProc, 0, 0, 0, false); + } + } + if ((storedProc & 0xFFFFFF00)) + { + if ((storedProc & 0xFF000000) == 0xFF000000) + { + fieldOfs = storedProc & 0x00FFFFFF; + recN1 = GetInfoRec(classVMT + cVmtSelfPtr); + if (recN1 && recN1->vmtInfo) + recN1->vmtInfo->AddField(0, 0, FIELD_PUBLIC, fieldOfs, -1, name, typeName); + } + else if ((storedProc & 0xFF000000) == 0xFE000000) + { + if ((storedProc & 0x00008000)) + vmtofs = -((int)storedProc & 0x0000FFFF); + else + vmtofs = storedProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + storedProc = *((DWORD*)(Code + posn)); + recN1 = GetInfoRec(storedProc); + if (!recN1) + recN1 = new InfoRec(Adr2Pos(storedProc), ikFunc); + else if (!recN1->procInfo) + recN1->procInfo = new InfoProcInfo; + recN1->kind = ikFunc; + recN1->type = "Boolean"; + if (!recN1->HasName()) + recN1->SetName(clsName + ".IsStored" + name); + recN1->procInfo->flags |= PF_METHOD; + recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); + mainForm->AnalyzeProc1(storedProc, 0, 0, 0, false); + } + else + { + recN1 = GetInfoRec(storedProc); + if (!recN1) + recN1 = new InfoRec(Adr2Pos(storedProc), ikFunc); + else if (!recN1->procInfo) + recN1->procInfo = new InfoProcInfo; + recN1->kind = ikFunc; + recN1->type = "Boolean"; + if (!recN1->HasName()) + recN1->SetName(clsName + ".IsStored" + name); + recN1->procInfo->flags |= PF_METHOD; + recN1->procInfo->AddArg(0x21, 0, 4, "Self", clsName); + recN1->procInfo->AddArg(0x21, 1, 4, "Value", typeName); + mainForm->AnalyzeProc1(storedProc, 0, 0, 0, false); + } + } + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::FillClassViewer() +{ + PVmtListRec recV; + + mainForm->tvClassesFull->Items->Clear(); + const int cntVmt = VmtList->Count; + if (!cntVmt) return; + + int stepMask = StartProgress(cntVmt, "Building ClassViewer Tree..."); + TStringList *tmpList = new TStringList; + tmpList->Sorted = false; + + mainForm->tvClassesFull->Items->BeginUpdate(); + + for (int n = 0; n < cntVmt && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + + recV = (PVmtListRec)VmtList->Items[n]; + UpdateStatusBar(GetClsName(recV->vmtAdr)); + mainForm->FillClassViewerOne(n, tmpList, &Terminated); + } + + mainForm->tvClassesFull->Items->EndUpdate(); + + ProjectModified = true; + ClassTreeDone = true; + delete tmpList; + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::AnalyzeDC() +{ + int n, m, k, dotpos, pos, stepMask, instrLen; + DWORD vmtAdr, adr, procAdr, stopAt, classAdr; + String className, name; + PVmtListRec recV; + PInfoRec recN, recN1, recN2; + PARGINFO argInfo; + PMethodRec recM, recM1; + DISINFO disInfo; + + //Ñîçäàåì âðåìåííûé ñïèñîê ïàð (âûñîòà, àäðåñ VMT) + const int cntVmt = VmtList->Count; + if (!cntVmt) return; + + stepMask = StartProgress(cntVmt, "Analyzing Constructors and Destructors, step 1..."); + for (n = 0; n < cntVmt && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + recV = (PVmtListRec)VmtList->Items[n]; + vmtAdr = recV->vmtAdr; + className = GetClsName(vmtAdr); + UpdateStatusBar(className); + + //Destructor + pos = Adr2Pos(vmtAdr) - cVmtSelfPtr + cVmtDestroy; + adr = *((DWORD*)(Code + pos)); + if (IsValidImageAdr(adr)) + { + recN = GetInfoRec(adr); + if (recN && !recN->HasName()) + { + recN->kind = ikDestructor; + recN->SetName(className + ".Destroy"); + } + } + //Constructor + recN = GetInfoRec(vmtAdr); + + if (recN && recN->xrefs) + { + for (m = 0; m < recN->xrefs->Count; m++) + { + PXrefRec recX = (PXrefRec)recN->xrefs->Items[m]; + adr = recX->adr + recX->offset; + recN1 = GetInfoRec(adr); + if (recN1 && !recN1->HasName()) + { + if (IsFlagSet(cfProcStart, Adr2Pos(adr))) + { + recN1->kind = ikConstructor; + recN1->SetName(className + ".Create"); + } + } + } + } + } + StopProgress(); + stepMask = StartProgress(cntVmt, "Analyzing Constructors, step 2..."); + for (n = 0; n < cntVmt && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + recV = (PVmtListRec)VmtList->Items[n]; + vmtAdr = recV->vmtAdr; + stopAt = GetStopAt(vmtAdr - cVmtSelfPtr); + if (vmtAdr == stopAt) continue; + + className = GetClsName(vmtAdr); + UpdateStatusBar(className); + pos = Adr2Pos(vmtAdr) - cVmtSelfPtr + cVmtParent + 4; + + for (m = cVmtParent + 4;; m += 4, pos += 4) + { + if (Pos2Adr(pos) == stopAt) break; + procAdr = *((DWORD*)(Code + pos)); + if (m >= 0) + { + recN = GetInfoRec(procAdr); + if (recN && recN->kind == ikConstructor && !recN->HasName()) + { + classAdr = vmtAdr; + while (classAdr) + { + recM = mainForm->GetMethodInfo(classAdr, 'V', m); + if (recM) + { + name = recM->name; + if (name != "") + { + dotpos = name.Pos("."); + if (dotpos) + recN->SetName(className + name.SubString(dotpos, name.Length())); + else + recN->SetName(name); + break; + } + } + classAdr = GetParentAdr(classAdr); + } + } + } + } + } + StopProgress(); + stepMask = StartProgress(cntVmt, "Analyzing Dynamic Methods..."); + for (n = 0; n < cntVmt && !Terminated; n++) + { + if ((n & stepMask) == 0) UpdateProgress(); + recV = (PVmtListRec)VmtList->Items[n]; + vmtAdr = recV->vmtAdr; + className = GetClsName(vmtAdr); + UpdateStatusBar(className); + + recN = GetInfoRec(vmtAdr); + + if (recN && recN->vmtInfo->methods) + { + for (m = 0; m < recN->vmtInfo->methods->Count; m++) + { + recM = (PMethodRec)recN->vmtInfo->methods->Items[m]; + if (recM->kind == 'D') + { + recN1 = GetInfoRec(recM->address); + if (recN1) + { + classAdr = GetParentAdr(vmtAdr); + while (classAdr) + { + recM1 = mainForm->GetMethodInfo(classAdr, 'D', recM->id); + if (recM1) + { + recN2 = GetInfoRec(recM1->address); + if (recN2 && recN2->procInfo->args) + { + for (k = 0; k < recN2->procInfo->args->Count; k++) + { + if (!k) + recN1->procInfo->AddArg(0x21, 0, 4, "Self", className); + else + { + argInfo = (PARGINFO)recN2->procInfo->args->Items[k]; + recN1->procInfo->AddArg(argInfo); + } + } + } + } + classAdr = GetParentAdr(classAdr); + } + } + } + } + } + } + StopProgress(); +} +//--------------------------------------------------------------------------- +void __fastcall TAnalyzeThread::ClearPassFlags() +{ + if (!Terminated) mainForm->ClearPassFlags(); +} +//--------------------------------------------------------------------------- diff --git a/Threads.h b/Threads.h new file mode 100644 index 0000000..776e2f1 --- /dev/null +++ b/Threads.h @@ -0,0 +1,85 @@ +//--------------------------------------------------------------------------- +#ifndef ThreadsH +#define ThreadsH +//--------------------------------------------------------------------------- +#include +#include "Main.h" +#include "ProgressBar.h" +//--------------------------------------------------------------------------- +enum ThreadAnalysisOperation +{ + taStartPrBar, taUpdatePrBar, taUpdateStBar, + taUpdateUnits, taUpdateRTTIs, taUpdateVmtList, taUpdateStrings, taUpdateCode, taUpdateXrefs, + taUpdateShortClassViewer, taUpdateClassViewer, taUpdateBeforeClassViewer, + taFinished +}; +struct ThreadAnalysisData +{ + ThreadAnalysisData(int steps, const String& txt) + :pbSteps(steps), sbText(txt) {} + int pbSteps; + String sbText; +}; + +typedef struct +{ + int height; + DWORD vmtAdr; +} CVPair, *PCVPair; +//--------------------------------------------------------------------------- +#define LAST_ANALYZE_STEP 19 +class TAnalyzeThread : public TThread +{ +private: + TFMain_11011981 *mainForm; + TFProgressBar *pbForm; + int adrCnt; + + int __fastcall StartProgress(int pbMaxCount, const String& sbText); + void __fastcall UpdateProgress(); + void __fastcall StopProgress(); + void __fastcall UpdateStatusBar(int adr); + void __fastcall UpdateStatusBar(const String& sbText); + void __fastcall UpdateAddrInStatusBar(DWORD adr); + void __fastcall UpdateUnits(); + void __fastcall UpdateRTTIs(); + void __fastcall UpdateVmtList(); + void __fastcall UpdateStrings(); + void __fastcall UpdateCode(); + void __fastcall UpdateXrefs(); + void __fastcall UpdateShortClassViewer(); + void __fastcall UpdateClassViewer(); + void __fastcall UpdateBeforeClassViewer(); + void __fastcall StrapSysProcs(); + void __fastcall FindRTTIs(); + void __fastcall FindVMTs2(); //Äëÿ âåðñèè Äåëüôè2 (äðóãàÿ ñòðóêòóðà!) + void __fastcall FindVMTs(); + void __fastcall FindTypeFields(); + String __fastcall FindEvent(DWORD VmtAdr, String Name); + void __fastcall FindPrototypes(); + void __fastcall StrapVMTs(); + void __fastcall ScanCode(); + void __fastcall ScanCode1(); + void __fastcall ScanVMTs(); + void __fastcall ScanConsts(); + void __fastcall ScanGetSetStoredProcs(); + void __fastcall FindStrings(); + void __fastcall AnalyzeCode1(); + void __fastcall AnalyzeCode2(bool args); + void __fastcall AnalyzeCode3(); + void __fastcall PropagateClassProps(); + void __fastcall FillClassViewer(); + void __fastcall AnalyzeDC(); + + void __fastcall ClearPassFlags(); + +protected: + void __fastcall Execute(); +public: + __fastcall TAnalyzeThread(TFMain_11011981* AForm, TFProgressBar* ApbForm, bool AllValues); + __fastcall ~TAnalyzeThread(); + int __fastcall GetRetVal(); + bool all; //if false, only ClassViewer +}; +//--------------------------------------------------------------------------- +#endif diff --git a/TypeInfo.cpp b/TypeInfo.cpp new file mode 100644 index 0000000..622991f --- /dev/null +++ b/TypeInfo.cpp @@ -0,0 +1,2014 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "TypeInfo.h" +#include "Main.h" +#include "Misc.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" + +extern DWORD ImageBase; +extern DWORD CodeBase; +extern DWORD *Flags; +extern PInfoRec *Infos; +extern BYTE *Code; +extern int DelphiVersion; +extern TList *TypeList; +extern MKnowledgeBase KnowledgeBase; + +TFTypeInfo_11011981 *FTypeInfo_11011981; +//--------------------------------------------------------------------------- +__fastcall TFTypeInfo_11011981::TFTypeInfo_11011981(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TFTypeInfo_11011981::ShowKbInfo(MTypeInfo* tInfo) +{ + WORD Len; + String line; + + memDescription->ReadOnly = True; + Panel1->Visible = False; + + if (tInfo->ModuleID != 0xFFFF) + Caption = KnowledgeBase.GetModuleName(tInfo->ModuleID) + "."; + Caption = Caption + tInfo->TypeName; + if (tInfo->Size) + Caption = Caption + " (size = " + Val2Str0(tInfo->Size) + ")"; + + memDescription->Clear(); + if (tInfo->Decl != "") memDescription->Lines->Add(tInfo->Decl); + if (tInfo->FieldsNum) + { + memDescription->Lines->Add("//FIELDS//"); + BYTE *p = tInfo->Fields; + FIELDINFO fInfo; + + for (int n = 0; n < tInfo->FieldsNum; n++) + { + fInfo.Scope = *p; p++; + fInfo.Offset = *((int*)p); p += 4; + fInfo.Case = *((int*)p); p += 4; + Len = *((WORD*)p); p += 2; + fInfo.Name = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + fInfo.Type = TrimTypeName(String((char*)p, Len)); p += Len + 1; + + line = "f" + Val2Str0(fInfo.Offset) + " "; + + switch (fInfo.Scope) + { + case 9: + line += "private"; + break; + case 10: + line += "protected"; + break; + case 11: + line += "public"; + break; + case 12: + line += "published"; + break; + } + if (fInfo.Case != -1) line += " case " + String(fInfo.Case); + line += " " + fInfo.Name + ":" + fInfo.Type; + memDescription->Lines->Add(line); + } + } + if (tInfo->PropsNum) + { + memDescription->Lines->Add("//PROPERTIES//"); + BYTE *p = tInfo->Props; + PROPINFO pInfo; + + for (int n = 0; n < tInfo->PropsNum; n++) + { + pInfo.Scope = *p; p++; + pInfo.Index = *((int*)p); p += 4; + pInfo.DispID = *((int*)p); p += 4; + Len = *((WORD*)p); p += 2; + pInfo.Name = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + pInfo.TypeDef = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + pInfo.ReadName = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + pInfo.WriteName = String((char*)p, Len); p += Len + 1; + Len = *((WORD*)p); p += 2; + pInfo.StoredName = String((char*)p, Len); p += Len + 1; + + line = ""; + + switch (pInfo.Scope) + { + case 9: + line += "private"; + break; + case 10: + line += "protected"; + break; + case 11: + line += "public"; + break; + case 12: + line += "published"; + break; + } + + line += " " + pInfo.Name + ":" + pInfo.TypeDef; + line += " " + pInfo.ReadName; + line += " " + pInfo.WriteName; + line += " " + pInfo.StoredName; + + if (pInfo.Index != -1) + { + switch (pInfo.Index & 6) + { + case 2: + line += " read"; + break; + case 4: + line += " write"; + break; + } + } + + memDescription->Lines->Add(line); + } + } + if (tInfo->MethodsNum) + { + memDescription->Lines->Add("//METHODS//"); + BYTE *p = tInfo->Methods; + METHODINFO mInfo; + + for (int n = 0; n < tInfo->MethodsNum; n++) + { + mInfo.Scope = *p; p++; + mInfo.MethodKind = *p; p++; + Len = *((WORD*)p); p += 2; + mInfo.Prototype = String((char*)p, Len); p += Len + 1; + + line = ""; + + switch (mInfo.Scope) + { + case 9: + line += "private"; + break; + case 10: + line += "protected"; + break; + case 11: + line += "public"; + break; + case 12: + line += "published"; + break; + } + + line += " " + mInfo.Prototype; + memDescription->Lines->Add(line); + } + } + if (tInfo->Dump) + { + memDescription->Lines->Add("//Dump//"); + BYTE *p = tInfo->Dump; line = ""; + for (int n = 0; n < tInfo->DumpSz; n++) + { + if (n) line += " "; + line += Val2Str2((int)*p); p++; + } + memDescription->Lines->Add(line); + } + ShowModal(); +} +//--------------------------------------------------------------------------- +String __fastcall GetVarTypeString(int val) +{ + String res = ""; + switch (val) + { + case 0: + res = "Empty"; + break; + case 1: + res = "Null"; + break; + case 2: + res = "Smallint"; + break; + case 3: + res = "Integer"; + break; + case 4: + res = "Single"; + break; + case 5: + res = "Double"; + break; + case 6: + res = "Currency"; + break; + case 7: + res = "Date"; + break; + case 8: + res = "OleStr"; + break; + case 9: + res = "Dispatch"; + break; + case 0xA: + res = "Error"; + break; + case 0xB: + res = "Boolean"; + break; + case 0xC: + res = "Variant"; + break; + case 0xD: + res = "Unknown"; + break; + case 0xE: + res = "Decimal"; + break; + case 0xF: + res = "Undef0F"; + break; + case 0x10: + res = "ShortInt"; + break; + case 0x11: + res = "Byte"; + break; + case 0x12: + res = "Word"; + break; + case 0x13: + res = "LongWord"; + break; + case 0x14: + res = "Int64"; + break; + case 0x15: + res = "Word64"; + break; + case 0x48: + res = "StrArg"; + break; + case 0x100: + res = "String"; + break; + case 0x101: + res = "Any"; + break; + case 0xFFF: + res = "TypeMask"; + break; + case 0x2000: + res = "Array"; + break; + case 0x4000: + res = "ByRef"; + break; + } + return res; +} +//--------------------------------------------------------------------------- +String __fastcall TFTypeInfo_11011981::GetRTTI(DWORD adr) +{ + bool found; + BYTE floatType, methodKind, paramCount, numOps, ordType, callConv, paramFlags, propFlags, flags, dimCount; + WORD dw, propCount, methCnt; + DWORD minValue, maxValue, minValueB, maxValueB; + int i, m, n, vmtofs, pos, posn, spos, _ap; + __int64 minInt64Value, maxInt64Value; + int elSize, varType; //for tkDynArray + DWORD elType; //for tkDynArray + DWORD typeAdr, classVMT, parentAdr, Size, elNum, elOff, resultTypeAdr; + DWORD propType, getProc, setProc, storedProc, methAdr, procSig; + BYTE GUID[16]; + String typname, name, FldFileName; + FILE *fldf; + PInfoRec recN; + + RTTIAdr = adr; + _ap = Adr2Pos(RTTIAdr); pos = _ap; + pos += 4; + RTTIKind = Code[pos]; pos++; + BYTE len = Code[pos]; pos++; + RTTIName = String((char*)(Code + pos), len); pos += len; + Caption = RTTIName; + String result = "", proto; + + switch (RTTIKind) + { + case ikUnknown: + break; + case ikInteger: + case ikChar: + case ikWChar: + ordType = Code[pos]; pos++; + minValue = *((DWORD*)(Code + pos)); pos += 4; + maxValue = *((DWORD*)(Code + pos)); + //Signed type + if (!(ordType & 1)) + result = IntToStr((int)minValue) + ".." + IntToStr((int)maxValue); + //Unsigned type + else + result = "$" + IntToHex((__int64)minValue, 0) + ".." + "$" + IntToHex((__int64)maxValue, 0); + break; + case ikEnumeration: + result = "("; + ordType = Code[pos]; pos++; + minValue = *((DWORD*)(Code + pos)); pos += 4; + maxValue = *((DWORD*)(Code + pos)); pos += 4; + //BaseTypeAdr + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + + if (SameText(RTTIName, "ByteBool") || + SameText(RTTIName, "WordBool") || + SameText(RTTIName, "LongBool")) + { + minValue = 0; + maxValue = 1; + } + + //If BaseTypeAdr != SelfAdr then fields extracted from BaseType + if (typeAdr != RTTIAdr) + { + pos = Adr2Pos(typeAdr); + pos += 4; //SelfPointer + pos++; //typeKind + len = Code[pos]; pos++; + pos += len; //BaseClassName + pos++; //ordType + minValueB = *((DWORD*)(Code + pos)); pos += 4; + maxValueB = *((DWORD*)(Code + pos)); pos += 4; + pos += 4; //BaseClassPtr + } + else + { + minValueB = minValue; + maxValueB = maxValue; + } + + for (i = minValueB; i <= maxValueB; i++) + { + len = Code[pos]; pos++; + if (i >= minValue && i <= maxValue) + { + name = String((char*)(Code + pos), len); + if (i != minValue) result += ", "; + result += name; + } + pos += len; + } + result += ")"; + //UnitName + len = Code[pos]; + if (IsValidName(len, pos + 1)) + { + pos++; + Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; + } + break; + case ikFloat: + if (SameText(RTTIName, "Single") || + SameText(RTTIName, "Double") || + SameText(RTTIName, "Extended") || + SameText(RTTIName, "Comp") || + SameText(RTTIName, "Currency")) + result = "float"; + else + { + floatType = Code[pos]; pos++; + result = "type "; + switch (floatType) + { + case FtSingle: + result += "Single"; + break; + case FtDouble: + result += "Double"; + break; + case FtExtended: + result += "Extended"; + break; + case FtComp: + result += "Comp"; + break; + case FtCurr: + result += "Currency"; + break; + } + } + break; + case ikString: + result = "String"; + break; + case ikSet: + result = "set of "; + pos++; //skip ordType + typeAdr = *((DWORD*)(Code + pos)); + result = "set of " + GetTypeName(typeAdr); + break; + case ikClass: + result = "class"; + classVMT = *((DWORD*)(Code + pos)); pos += 4; + parentAdr = *((DWORD*)(Code + pos)); pos += 4; + if (parentAdr) result += "(" + GetTypeName(parentAdr) + ")"; + propCount = *((WORD*)(Code + pos)); pos += 2; + + //UnitName + len = Code[pos]; pos++; + Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; + pos += len; + + propCount = *((WORD*)(Code + pos)); pos += 2; + for (i = 0; i < propCount; i++) + { + propType = *((DWORD*)(Code + pos)); pos += 4; + posn = Adr2Pos(propType); posn += 4; + posn++; //property type + len = Code[posn]; posn++; + typname = String((char*)(Code + posn), len); + getProc = *((DWORD*)(Code + pos)); pos += 4; + setProc = *((DWORD*)(Code + pos)); pos += 4; + storedProc = *((DWORD*)(Code + pos)); pos += 4; + //idx + pos += 4; + //defval + pos += 4; + //nameIdx + pos += 2; + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += "\n" + name + ":" + typname; + if ((getProc & 0xFFFFFF00)) + { + result += "\n read "; + if ((getProc & 0xFF000000) == 0xFF000000) + result += name + " f" + Val2Str0(getProc & 0x00FFFFFF); + else if ((getProc & 0xFF000000) == 0xFE000000) + { + if ((getProc & 0x00008000)) + vmtofs = -((int)getProc & 0x0000FFFF); + else + vmtofs = getProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + getProc = *((DWORD*)(Code + posn)); + + result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(getProc); + recN = GetInfoRec(getProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + else + { + result += Val2Str0(getProc); + recN = GetInfoRec(getProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + } + if ((setProc & 0xFFFFFF00)) + { + result += "\n write "; + if ((setProc & 0xFF000000) == 0xFF000000) + result += name + " f" + Val2Str0(setProc & 0x00FFFFFF); + else if ((setProc & 0xFF000000) == 0xFE000000) + { + if ((setProc & 0x00008000)) + vmtofs = -((int)setProc & 0x0000FFFF); + else \ + vmtofs = setProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + setProc = *((DWORD*)(Code + posn)); + result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(setProc); + recN = GetInfoRec(setProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + else + { + result += Val2Str0(setProc); + recN = GetInfoRec(setProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + } + if ((storedProc & 0xFFFFFF00)) + { + result += "\n stored "; + if ((storedProc & 0xFF000000) == 0xFF000000) + result += name + " f" + Val2Str0(storedProc & 0x00FFFFFF); + else if ((storedProc & 0xFF000000) == 0xFE000000) + { + if ((storedProc & 0x00008000)) + vmtofs = -((int)storedProc & 0x0000FFFF); + else + vmtofs = storedProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + storedProc = *((DWORD*)(Code + posn)); + result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(storedProc); + recN = GetInfoRec(storedProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + else + { + result += Val2Str0(storedProc); + recN = GetInfoRec(storedProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + } + } + if (DelphiVersion >= 2010) + { + propCount = *((WORD*)(Code + pos)); pos += 2; + for (i = 0; i < propCount; i++) + { + //Flags + propFlags = Code[pos]; pos++; + //PPropInfo + propType = *((DWORD*)(Code + pos)); pos += 4; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + spos = pos; + //PropInfo + pos = Adr2Pos(propType); + propType = *((DWORD*)(Code + pos)); pos += 4; + + if (IsFlagSet(cfImport, Adr2Pos(propType))) + { + recN = GetInfoRec(propType); + typname = recN->GetName(); + } + else + { + posn = Adr2Pos(propType); + posn += 4; + posn++; //property type + len = Code[posn]; posn++; + typname = String((char*)(Code + posn), len); + } + + getProc = *((DWORD*)(Code + pos)); pos += 4; + setProc = *((DWORD*)(Code + pos)); pos += 4; + storedProc = *((DWORD*)(Code + pos)); pos += 4; + //idx + pos += 4; + //defval + pos += 4; + //nameIdx + pos += 2; + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += "\n" + name + ":" + typname; + if ((getProc & 0xFFFFFF00)) + { + result += "\n read "; + if ((getProc & 0xFF000000) == 0xFF000000) + result += name + " f" + Val2Str0(getProc & 0x00FFFFFF); + else if ((getProc & 0xFF000000) == 0xFE000000) + { + if ((getProc & 0x00008000)) + vmtofs = -((int)getProc & 0x0000FFFF); + else + vmtofs = getProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + getProc = *((DWORD*)(Code + pos)); + + result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(getProc); + recN = GetInfoRec(getProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + else + { + result += Val2Str0(getProc); + recN = GetInfoRec(getProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + } + if ((setProc & 0xFFFFFF00)) + { + result += "\n write "; + if ((setProc & 0xFF000000) == 0xFF000000) + result += name + " f" + Val2Str0(setProc & 0x00FFFFFF); + else if ((setProc & 0xFF000000) == 0xFE000000) + { + if ((setProc & 0x00008000)) + vmtofs = -((int)setProc & 0x0000FFFF); + else + vmtofs = setProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + setProc = *((DWORD*)(Code + pos)); + result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(setProc); + recN = GetInfoRec(setProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + else + { + result += Val2Str0(setProc); + recN = GetInfoRec(setProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + } + if ((storedProc & 0xFFFFFF00)) + { + result += "\n stored "; + if ((storedProc & 0xFF000000) == 0xFF000000) + result += name + " f" + Val2Str0(storedProc & 0x00FFFFFF); + else if ((storedProc & 0xFF000000) == 0xFE000000) + { + if ((storedProc & 0x00008000)) + vmtofs = -((int)storedProc & 0x0000FFFF); + else + vmtofs = storedProc & 0x0000FFFF; + posn = Adr2Pos(classVMT) + vmtofs; + storedProc = *((DWORD*)(Code + pos)); + result += " vmt" + Val2Str0(vmtofs) + " " + Val2Str0(storedProc); + recN = GetInfoRec(storedProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + else + { + result += Val2Str0(storedProc); + recN = GetInfoRec(storedProc); + if (recN && recN->HasName()) result += " " + recN->GetName(); + } + } + pos = spos; + } + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + if (DelphiVersion >= 2012) + { + //ArrayPropCount + propCount = *((WORD*)(Code + pos)); pos += 2; + for (i = 0; i < propCount; i++) + { + //Flags + pos++; + //ReadIndex + pos += 2; + //WriteIndex + pos += 2; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += "\n" + name; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + } + } + break; + case ikMethod: + methodKind = Code[pos]; pos++; + switch (methodKind) + { + case MkProcedure: + result = "procedure"; + break; + case MkFunction: + result = "function"; + break; + case MkConstructor: + result = "constructor"; + break; + case MkDestructor: + result = "destructor"; + break; + case MkClassProcedure: + result = "class procedure"; + break; + case MkClassFunction: + result = "class function"; + break; + case 6: + if (DelphiVersion < 2009) + result = "safeprocedure"; + else + result = "class constructor"; + break; + case 7: + if (DelphiVersion < 2009) + result = "safefunction"; + else + result = "operator overload"; + break; + } + + paramCount = Code[pos]; pos++; + if (paramCount > 0) proto = "("; + + for (i = 0; i < paramCount; i++) + { + BYTE paramFlags = Code[pos]; pos++; + if (paramFlags & PfVar) + proto += "var "; + else if (paramFlags & PfConst) + proto += "const "; + else if (paramFlags & PfArray) + proto += "array "; + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + proto += name + ":"; + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + proto += name; + if (i != paramCount - 1) proto += "; "; + } + if (paramCount > 0) proto += ")"; + + if (methodKind) + { + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + if (DelphiVersion > 6) + { + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + name = GetTypeName(typeAdr); + } + proto += ":" + name; + } + if (DelphiVersion > 6) + { + //CC + callConv = Code[pos]; pos++; + //ParamTypeRefs + pos += 4*paramCount; + if (DelphiVersion >= 2010) + { + //MethSig + procSig = *((DWORD*)(Code + pos)); pos += 4; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + posn = Adr2Pos(procSig); + else + posn = _ap + procSig; + //Flags + flags = Code[posn]; posn++; + if (flags != 0xFF) + { + //CC + callConv = Code[posn]; posn++; + //ResultType + resultTypeAdr = *((DWORD*)(Code + posn)); posn += 4; + //ParamCount + paramCount = Code[posn]; posn++; + if (paramCount > 0) proto = "("; + for (i = 0; i < paramCount; i++) + { + BYTE paramFlags = Code[posn]; posn++; + if (paramFlags & PfVar) + proto += "var "; + else if (paramFlags & PfConst) + proto += "const "; + else if (paramFlags & PfArray) + proto += "array "; + typeAdr = *((DWORD*)(Code + posn)); posn += 4; + len = Code[posn]; posn++; + name = String((char*)(Code + posn), len); posn += len; + proto += name + ":" + GetTypeName(typeAdr); + if (i != paramCount - 1) proto += "; "; + //AttrData + dw = *((WORD*)(Code + posn)); + posn += dw;//ATR!! + } + if (paramCount > 0) proto += ")"; + if (resultTypeAdr) proto += ":" + GetTypeName(resultTypeAdr); + } + } + } + } + result += proto + " of object;"; + break; + case ikLString: + result = "String"; + break; + case ikWString: + result = "WideString"; + break; + case ikVariant: + result = "Variant"; + break; + case ikArray: + Size = *((DWORD*)(Code + pos)); pos += 4; + elNum = *((DWORD*)(Code + pos)); pos += 4; + resultTypeAdr = *((DWORD*)(Code + pos)); pos += 4; + result = "array [1.." + String(elNum); + if (DelphiVersion >= 2010) + { + result = "array ["; + //DimCount + dimCount = Code[pos]; pos++; + for (i = 0; i < dimCount; i++) + { + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + if (IsValidImageAdr(typeAdr)) + result += GetTypeName(typeAdr); + else + { + if (!typeAdr) + { + if (dimCount == 1) + result += "1.." + String(elNum); + else + result += "1..?"; + } + else + result += "1.." + Val2Str8(typeAdr); + } + if (i != dimCount - 1) result += ","; + } + } + result += "] of " + GetTypeName(resultTypeAdr); + break; + case ikRecord: + Size = *((DWORD*)(Code + pos)); pos += 4; + result = RTTIName + " = record//size=0x" + Val2Str0(Size); + elNum = *((DWORD*)(Code + pos)); pos += 4; //FldCount + if (elNum) + { + for (i = 0; i < elNum; i++) + { + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + elOff = *((DWORD*)(Code + pos)); pos += 4; + result += "\nf" + Val2Str0(elOff) + ":" + GetTypeName(typeAdr) + ";//f" + Val2Str0(elOff); + } + result += "\nend;"; + } + + if (DelphiVersion >= 2010) + { + //NumOps + numOps = Code[pos]; pos++; + for (i = 0; i < numOps; i++) //RecOps + { + pos += 4; + } + elNum = *((DWORD*)(Code + pos)); pos += 4; //RecFldCnt + + if (elNum) + { + for (i = 0; i < elNum; i++) + { + //TypeRef + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + //FldOffset + elOff = *((DWORD*)(Code + pos)); pos += 4; + //Flags + pos++; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += "\n" + name + ":" + GetTypeName(typeAdr) + ";//f" + Val2Str0(elOff); + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + result += "\nend;"; + } + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + if (DelphiVersion >= 2012) + { + methCnt = *((WORD*)(Code + pos)); pos += 2; + if (methCnt > 0) result += "\n//Methods:"; + for (m = 0; m < methCnt; m++) + { + //Flags + pos++; + //Code + methAdr = *((DWORD*)(Code + pos)); pos += 4; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += "\n" + name; + //ProcedureSignature + //Flags + flags = Code[pos]; pos++; + if (flags != 0xFF) + { + //CC + pos++; + //ResultType + resultTypeAdr = *((DWORD*)(Code + pos)); pos += 4; + //ParamCnt + paramCount = Code[pos]; pos++; + if (paramCount > 0) result += "("; + //Params + for (n = 0; n < paramCount; n++) + { + //Flags + pos++; + //ParamType + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += name + ":" + GetTypeName(typeAdr); + if (n != paramCount - 1) result += ";"; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + if (paramCount > 0) result += ")"; + if (resultTypeAdr) result += ":" + GetTypeName(resultTypeAdr); + result += ";//" + Val2Str8(methAdr); + } + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + } + } + break; + case ikInterface: + result = "interface"; + //IntfParent + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + if (typeAdr) result += "(" + GetTypeName(typeAdr) + ")"; + //IntfFlags + pos++; + //GUID + memmove(GUID, &Code[pos], 16); pos += 16; + result += Guid2String(GUID) + "\n"; + + //UnitName + len = Code[pos]; pos++; + Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; + pos += len; + + //Methods + propCount = *((WORD*)(Code + pos)); pos += 2; + result += "Methods Count = " + String(propCount); + if (DelphiVersion >= 6) + { + //RttiCount + dw = *((WORD*)(Code + pos)); pos += 2; + if (dw != 0xFFFF) + { + if (DelphiVersion >= 2010) + { + for (i = 0; i < propCount; i++) + { + //Name + len = Code[pos]; pos++; + result += "\n" + String((char*)(Code + pos), len); pos += len; + //Kind + methodKind = Code[pos]; pos++; + //CallConv + pos++; + //ParamCount + paramCount = Code[pos]; pos++; + if (paramCount) result += "("; + for (m = 0; m < paramCount; m++) + { + if (m) result += ";"; + //Flags + pos++; + //ParamName + len = Code[pos]; pos++; + result += String((char*)(Code + pos), len); pos += len; + //TypeName + len = Code[pos]; pos++; + result += ":" + String((char*)(Code + pos), len); pos += len; + //ParamType + pos += 4; + } + if (paramCount) result += ")"; + if (methodKind) + { + result += ":"; + //ResultTypeName + len = Code[pos]; pos++; + result += String((char*)(Code + pos), len); pos += len; + if (len) + { + //ResultType + pos += 4; + } + } + } + } + else + { + for (i = 0; i < propCount; i++) + { + //PropType + pos += 4; + //GetProc + pos += 4; + //SetProc + pos += 4; + //StoredProc + pos += 4; + //Index + pos += 4; + //Default + pos += 4; + //NameIndex + pos += 2; + //Name + len = Code[pos]; pos++; + result += "\n" + String((char*)(Code + pos), len); pos += len; + } + } + } + } + break; + case ikInt64: + minInt64Value = *((__int64*)(Code + pos)); pos += sizeof(__int64); + maxInt64Value = *((__int64*)(Code + pos)); + result = IntToStr(minInt64Value) + ".." + IntToStr(maxInt64Value); + break; + case ikDynArray: + //elSize + elSize = *((DWORD*)(Code + pos)); pos += 4; + //elType + elType = *((DWORD*)(Code + pos)); pos += 4; + result = "array of " + GetTypeName(elType); + //varType + varType = *((DWORD*)(Code + pos)); pos += 4; + if (DelphiVersion >= 6) + { + //elType2 + pos += 4; + //UnitName + len = Code[pos]; pos++; + Caption = String((char*)(Code + pos), len).Trim() + "." + Caption; + pos += len; + } + if (DelphiVersion >= 2010) + { + //DynArrElType + elType = *((DWORD*)(Code + pos)); + result = "array of " + GetTypeName(elType); + } + result += ";"; + if (elSize) result += "\n//elSize = " + Val2Str0(elSize); + if (varType != -1) result += "\n//varType equivalent: var" + GetVarTypeString(varType); + break; + case ikUString: + result = "UString"; + break; + case ikClassRef: //0x13 + typeAdr = *((DWORD*)(Code + pos)); + if (typeAdr) result = "class of " + GetTypeName(typeAdr); + break; + case ikPointer: //0x14 + typeAdr = *((DWORD*)(Code + pos)); + if (typeAdr) result = "^" + GetTypeName(typeAdr); + break; + case ikProcedure: //0x15 + result = RTTIName; + //MethSig + procSig = *((DWORD*)(Code + pos)); pos += 4; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + pos = Adr2Pos(procSig); + else + pos = _ap + procSig; + //Flags + flags = Code[pos]; pos++; + if (flags != 0xFF) + { + //CallConv + callConv = Code[pos]; pos++; + //ResultType + resultTypeAdr = *((DWORD*)(Code + pos)); pos += 4; + if (resultTypeAdr) + result = "function "; + else + result = "procedure "; + result += RTTIName; + + //ParamCount + paramCount = Code[pos]; pos++; + + if (paramCount) result += "("; + for (i = 0; i < paramCount; i++) + { + //Flags + paramFlags = Code[pos]; pos++; + if (paramFlags & 1) result += "var "; + if (paramFlags & 2) result += "const "; + //ParamType + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + //Name + len = Code[pos]; pos++; + result += String((char*)(Code + pos), len) + ":"; + pos += len; + result += GetTypeName(typeAdr); + if (i != paramCount - 1) result += "; "; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + if (paramCount) result += ")"; + + if (resultTypeAdr) result += ":" + GetTypeName(resultTypeAdr); + result += ";"; + switch (callConv) + { + case 1: + result += " cdecl;"; + break; + case 2: + result += " pascal;"; + break; + case 3: + result += " stdcall;"; + break; + case 4: + result += " safecall;"; + break; + } + } + } + break; + } + return result; +} +//--------------------------------------------------------------------- +void __fastcall TFTypeInfo_11011981::ShowRTTI(DWORD adr) +{ + memDescription->ReadOnly = True; + Panel1->Visible = False; + + String line = GetRTTI(adr); + if (line != "") + { + memDescription->Clear(); + int len = line.Length(); + int b = 1, e = line.Pos("\n"); + while (1) + { + if (e) + { + line[e] = ' '; + memDescription->Lines->Add(line.SubString(b, e - b)); + } + else + { + memDescription->Lines->Add(line.SubString(b, len - b + 1)); + break; + } + b = e + 1; e = line.Pos("\n"); + } + if (RTTIKind == ikDynArray) + { + memDescription->ReadOnly = False; + Panel1->Visible = True; + } + ShowModal(); + } +} +//--------------------------------------------------------------------- +String __fastcall Guid2String(BYTE* Guid) +{ + int n; + char sbyte[8]; + String Result = "['{"; + + for (int i = 0; i < 16; i++) + { + switch (i) + { + case 0: + case 1: + case 2: + case 3: + n = 3 - i; + break; + case 4: + n = 5; + break; + case 5: + n = 4; + break; + case 6: + n = 7; + break; + case 7: + n = 6; + break; + default: + n = i; + break; + } + if (i == 4 || i == 6 || i == 8 || i == 10) Result += '-'; + sprintf(sbyte, "%02X", Guid[n]); + Result += String(sbyte); + } + Result += "}']"; + return Result; +} +//--------------------------------------------------------------------- +void __fastcall TFTypeInfo_11011981::FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + if (Key == VK_ESCAPE) ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TFTypeInfo_11011981::bSaveClick(TObject *Sender) +{ + BYTE len; + int pos, p; + String line, decl; + + for (int n = 0; n < memDescription->Lines->Count; n++) + { + line = memDescription->Lines->Strings[n].Trim(); + if (line == "") continue; + decl += line; + } + decl = decl.Trim(); + p = decl.Pos(";"); + if (p > 0) + { + decl = decl.SubString(1, p - 1); + } + + pos = Adr2Pos(RTTIAdr); + pos += 4; + pos++;//Kind + len = Code[pos]; pos++; + pos += len;//Name + + switch (RTTIKind) + { + case ikDynArray: + //elSize + pos += 4; + //elType + *((DWORD*)(Code + pos)) = GetOwnTypeAdr(GetArrayElementType(decl)); + break; + } + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TFTypeInfo_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- +FIELD_INFO* __fastcall FindFieldInfoByOffset(TList* List, int Offset) +{ + for (int n = 0; n < List->Count; n++) + { + FIELD_INFO* fInfo = (FIELD_INFO*)List->Items[n]; + if (fInfo->Offset == Offset) + return fInfo; + } + return 0; +} +//--------------------------------------------------------------------------- +String __fastcall TFTypeInfo_11011981::GetCppTypeInfo(DWORD adr, int* o_pSize, int action) +{ + bool found; + BYTE methodKind, paramCount, numOps, ordType, callConv, paramFlags, propFlags, flags, dimCount, len; + WORD dw, propCount, methCnt; + DWORD k, minValue, maxValue, minValueB, maxValueB; + int i, j, m, n, vmtofs, pos, posn, spos, _ap, curOfs, typeKind, typeSize, fieldsNum, intfNum, size, prevOfs; + DWORD elType; //for tkDynArray + DWORD typeAdr, classVMT, parentAdr, elNum, elOff, resultTypeAdr; + DWORD propType, getProc, setProc, storedProc, methAdr, procSig; + BYTE GUID[16]; + String typname, name, FldFileName, bfZeroes, result, item; + FILE *fldf; + PInfoRec recN; + MTypeInfo tInfo; + TList* fieldsList; + TStringList* intfList; + FIELD_INFO* FieldInfo;//For records + PFIELDINFO fInfo;//for VMT + + RTTIAdr = adr; + recN = GetInfoRec(adr); + if (!adr || !recN) return ""; + + if (recN->kind != ikVMT && recN->kind != ikUnknown) + { + _ap = Adr2Pos(RTTIAdr); pos = _ap; + pos += 4; + RTTIKind = Code[pos]; pos++; + len = Code[pos]; pos++; + RTTIName = String((char*)(Code + pos), len); pos += len; + } + else + { + RTTIKind = ikVMT; + RTTIName = recN->GetName(); + } + RTTIName = SanitizeName(RTTIName); + + result = ""; + switch (RTTIKind) + { + case ikUnknown: + break; + case ikInteger: + case ikChar: + case ikWChar: + ordType = Code[pos]; pos++; + //Unsigned type + if ((ordType & 1) != 0) + result += "unsigned "; + ordType &= 0xFE;//Clean sign bit + if (ordType == 0) + result += "char"; + else if (ordType == 2) + result += "short"; + else if (ordType == 4) + result += "int"; + break; + case ikEnumeration: + ordType = Code[pos]; pos++; + minValue = *((DWORD*)(Code + pos)); pos += 4; + maxValue = *((DWORD*)(Code + pos)); pos += 4; + //BaseTypeAdr + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + //If BaseTypeAdr != SelfAdr then fields extracted from BaseType + if (typeAdr != RTTIAdr) + { + pos = Adr2Pos(typeAdr); + pos += 4; //SelfPointer + pos++; //typeKind + len = Code[pos]; pos++; + pos += len; //BaseClassName + pos++; //ordType + minValueB = *((DWORD*)(Code + pos)); pos += 4; + maxValueB = *((DWORD*)(Code + pos)); pos += 4; + pos += 4; //BaseClassPtr + } + else + { + minValueB = minValue; + maxValueB = maxValue; + } + + bfZeroes = ""; + for (i = minValueB, k = 1; i <= maxValueB; i++) + { + len = Code[pos]; pos++; + if (i >= minValue && i <= maxValue) + { + name = String((char*)(Code + pos), len); + if (i != minValue) result += ",\n"; + if (action == 1) result += "bf_";//Make bitfield info + result += name; + if (action == 1) + { + if (k == 0) + { + bfZeroes += "00000000"; + k = 1; + } + if (k <= 0x80000000) + { + result += " = 0x" + Val2Str0(k) + bfZeroes; + k <<= 1; + } + } + } + pos += len; + } + *o_pSize = maxValueB - minValueB + 1; + break; + case ikString: + result = "String"; + break; + case ikSet: + pos++; //skip ordType + typeAdr = *((DWORD*)(Code + pos)); + result = GetCppTypeInfo(typeAdr, o_pSize, 1); + break; + case ikMethod: + result = "__fastcall (*P" + RTTIName + ")("; + methodKind = Code[pos]; pos++; + paramCount = Code[pos]; pos++; + + for (i = 0; i < paramCount; i++) + { + if (i) result += ", "; + BYTE paramFlags = Code[pos]; pos++; + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + len = Code[pos]; pos++; + typname = String((char*)(Code + pos), len); pos += len; + typeKind = GetTypeKind(typname, &size); + if (typeKind == ikVMT || typeKind == ikProcedure) + result += "struct "; + result += SanitizeName(typname); + if (typeKind == ikVMT) + result += "*"; + if (paramFlags & PfVar) + result += "*"; + result += " " + name; + } + result += ")"; + + if (methodKind) + { + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + if (DelphiVersion > 6) + { + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + name = GetTypeName(typeAdr); + } + typeKind = GetTypeKind(name, &size); + if (typeKind == ikVMT) + result = SanitizeName(name) + "* " + result; + else + result = SanitizeName(name) + " " + result; + } + else + result = "void " + result; + if (DelphiVersion > 6) + { + //CC + callConv = Code[pos]; pos++; + //ParamTypeRefs + pos += 4*paramCount; + if (DelphiVersion >= 2010) + { + //MethSig + procSig = *((DWORD*)(Code + pos)); pos += 4; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + posn = Adr2Pos(procSig); + else + posn = _ap + procSig; + //Flags + flags = Code[posn]; posn++; + if (flags != 0xFF) + { + //CC + callConv = Code[posn]; posn++; + //ResultType + resultTypeAdr = *((DWORD*)(Code + posn)); posn += 4; + //ParamCount + paramCount = Code[posn]; posn++; + result = "__fastcall (*P" + RTTIName + ")("; + for (i = 0; i < paramCount; i++) + { + if (i) result += ", "; + BYTE paramFlags = Code[posn]; posn++; + typeAdr = *((DWORD*)(Code + posn)); posn += 4; + len = Code[posn]; posn++; + name = String((char*)(Code + posn), len); posn += len; + typname = GetTypeName(typeAdr); + typeKind = GetTypeKind(typname, &size); + if (typeKind == ikVMT || typeKind == ikProcedure) + result += "struct "; + result += SanitizeName(typname); + if (typeKind == ikVMT) + result += "*"; + if (paramFlags & PfVar) + result += "*"; + result += " " + name; + //AttrData + dw = *((WORD*)(Code + posn)); + posn += dw;//ATR!! + } + result += ")"; + if (resultTypeAdr) + { + typname = GetTypeName(resultTypeAdr); + typeKind = GetTypeKind(typname, &size); + if (typeKind == ikVMT) + result = SanitizeName(typname) + "* " + result; + else + result = SanitizeName(typname) + " " + result; + } + else + result = "void " + result; + } + } + } + } + break; + case ikLString: + result = "String"; + break; + case ikWString: + result = "WideString"; + break; + case ikArray: + *o_pSize = *((DWORD*)(Code + pos)); pos += 4; + elNum = *((DWORD*)(Code + pos)); pos += 4; + resultTypeAdr = *((DWORD*)(Code + pos)); pos += 4; + result = GetTypeName(resultTypeAdr) + " %s"; + + if (DelphiVersion >= 2010) + { + //DimCount + dimCount = Code[pos]; pos++; + for (i = 0; i < dimCount; i++) + { + result += "["; + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + if (IsValidImageAdr(typeAdr)) + { + typname = GetTypeName(typeAdr); + if (SameText(typname, "Boolean")) + result += "0x2"; + else + result += typname; + } + else + { + if (!typeAdr) + { + if (dimCount == 1) + result += "0x" + Val2Str0(elNum); + else + result += "?"; + } + else + result += Val2Str8(typeAdr); + } + result += "]"; + } + } + result += ";//size=0x" + Val2Str0(*o_pSize) + "\n\n"; + break; + case ikRecord: + fieldsList = new TList; + *o_pSize = *((DWORD*)(Code + pos)); pos += 4; + elNum = *((DWORD*)(Code + pos)); pos += 4; //FldCount + //First cycle - fill fieldsList + if (elNum) + { + curOfs = 0; + for (i = 0; i < elNum; i++) + { + FieldInfo = new FIELD_INFO; + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + typname = GetTypeName(typeAdr); + elOff = *((DWORD*)(Code + pos)); pos += 4; + FieldInfo->Offset = elOff; + //Find type size + GetTypeKind(typname, &typeSize); + FieldInfo->Size = typeSize; + FieldInfo->Name = ""; + FieldInfo->Type = typname; + fieldsList->Add((void*)FieldInfo); + } + } + if (DelphiVersion >= 2010) + { + //NumOps + numOps = Code[pos]; pos++; + for (i = 0; i < numOps; i++) //RecOps + { + pos += 4; + } + elNum = *((DWORD*)(Code + pos)); pos += 4; //RecFldCnt + + if (elNum) + { + curOfs = 0; + for (i = 0; i < elNum; i++) + { + //TypeRef + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + typname = GetTypeName(typeAdr); + //FldOffset + elOff = *((DWORD*)(Code + pos)); pos += 4; + GetTypeKind(typname, &typeSize); + //Flags + pos++; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + FieldInfo = FindFieldInfoByOffset(fieldsList, elOff); + //If field with elOff exists then add name + if (FieldInfo) + { + if (FieldInfo->Name != "") + FieldInfo->Name += "|" + name; + else + FieldInfo->Name = name; + } + //Else add new FieldInfo + else + { + FieldInfo = new FIELD_INFO; + FieldInfo->Offset = elOff; + FieldInfo->Size = typeSize; + FieldInfo->Name = name; + FieldInfo->Type = typname; + fieldsList->Add((void*)FieldInfo); + } + } + } + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + if (DelphiVersion >= 2012) + { + methCnt = *((WORD*)(Code + pos)); pos += 2; + if (methCnt > 0) result += "\n//Methods:"; + for (m = 0; m < methCnt; m++) + { + //Flags + pos++; + //Code + methAdr = *((DWORD*)(Code + pos)); pos += 4; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += "\n" + name; + //ProcedureSignature + //Flags + flags = Code[pos]; pos++; + if (flags != 0xFF) + { + //CC + pos++; + //ResultType + resultTypeAdr = *((DWORD*)(Code + pos)); pos += 4; + //ParamCnt + paramCount = Code[pos]; pos++; + if (paramCount > 0) result += "("; + //Params + for (n = 0; n < paramCount; n++) + { + //Flags + pos++; + //ParamType + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + result += name + ":" + GetTypeName(typeAdr); + if (n != paramCount - 1) result += ";"; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + if (paramCount > 0) result += ")"; + if (resultTypeAdr) result += ":" + GetTypeName(resultTypeAdr); + result += ";//" + Val2Str8(methAdr); + } + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + } + } + fieldsList->Sort(FieldInfoCmpFunction); + //Second cycle - process fieldsList + curOfs = 0; + for (i = 0; i < fieldsList->Count; i++) + { + FieldInfo = (FIELD_INFO*)fieldsList->Items[i]; + elOff = FieldInfo->Offset; + //Skip big offsets (who knows about it's appearence, for example in TComponent) + if (elOff > *o_pSize) + break; + //Check long types like double, that has two referenced parts (or records and so on) + if (elOff < curOfs) + continue; + + if (elOff > curOfs) + { + result += "BYTE gap" + Val2Str0(curOfs) + "[0x" + Val2Str0(elOff - curOfs) + "];\n"; + curOfs = elOff; + } + + if (FieldInfo->Type != "?" && FieldInfo->Type != "") + { + typeKind = GetTypeKind(FieldInfo->Type, &size); + if (typeKind == ikEnumeration) size = 1; + //if (typeKind == ikSet) size = 1; + if (typeKind == ikMethod) size = 8; + if (typeKind == ikInterface) size = 4; + if (typeKind == ikRecord || typeKind == ikVMT) + result += "struct "; + result += SanitizeName(FieldInfo->Type); + if (typeKind == ikVMT) + result += "*"; + } + else + { + size = 1; + result += "BYTE"; + } + result += " f" + Val2Str0(FieldInfo->Offset); + if (FieldInfo->Name != "") + result += "_" + FieldInfo->Name; + result += ";\n"; + + curOfs += size; + } + if (curOfs < *o_pSize) + result += "BYTE gap" + Val2Str0(curOfs) + "[0x" + Val2Str0(*o_pSize - curOfs) + "];\n"; + + fieldsList->Clear(); + delete fieldsList; + break; + case ikInterface: + //IntfParent + pos += 4; + //IntfFlags + pos++; + //GUID + pos += 16; + //UnitName + len = Code[pos]; pos++; + pos += len; + //Methods + propCount = *((WORD*)(Code + pos)); pos += 2; + if (DelphiVersion >= 6) + { + //RttiCount + dw = *((WORD*)(Code + pos)); pos += 2; + if (dw != 0xFFFF) + { + if (DelphiVersion >= 2010) + { + for (i = 0; i < propCount; i++) + { + //Name + len = Code[pos]; pos++; + result += "\n" + String((char*)(Code + pos), len); pos += len; + //Kind + methodKind = Code[pos]; pos++; + //CallConv + pos++; + //ParamCount + paramCount = Code[pos]; pos++; + if (paramCount) result += "("; + for (m = 0; m < paramCount; m++) + { + if (m) result += ";"; + //Flags + pos++; + //ParamName + len = Code[pos]; pos++; + result += String((char*)(Code + pos), len); pos += len; + //TypeName + len = Code[pos]; pos++; + result += ":" + String((char*)(Code + pos), len); pos += len; + //ParamType + pos += 4; + } + if (paramCount) result += ")"; + if (methodKind) + { + result += ":"; + //ResultTypeName + len = Code[pos]; pos++; + result += String((char*)(Code + pos), len); pos += len; + if (len) + { + //ResultType + pos += 4; + } + } + } + } + else + { + for (i = 0; i < propCount; i++) + { + //PropType + pos += 4; + //GetProc + pos += 4; + //SetProc + pos += 4; + //StoredProc + pos += 4; + //Index + pos += 4; + //Default + pos += 4; + //NameIndex + pos += 2; + //Name + len = Code[pos]; pos++; + result += "\n" + String((char*)(Code + pos), len); pos += len; + } + } + } + } + break; + case ikInt64: + result = "__int64"; + break; + case ikDynArray: + //elSize + pos += 4; + //elType + elType = *((DWORD*)(Code + pos)); pos += 4; + result = SanitizeName(GetTypeName(elType)); + //varType + pos += 4; + if (DelphiVersion >= 6) + { + //elType2 + pos += 4; + //UnitName + len = Code[pos]; pos++; + pos += len; + } + if (DelphiVersion >= 2010) + { + //DynArrElType + elType = *((DWORD*)(Code + pos)); + result = SanitizeName(GetTypeName(elType)); + } + break; + case ikUString: + result = "UString"; + break; + case ikClassRef: //0x13 + typeAdr = *((DWORD*)(Code + pos)); + if (typeAdr) result = GetTypeName(typeAdr); + break; + case ikPointer: //0x14 + typeAdr = *((DWORD*)(Code + pos)); + if (typeAdr) result = GetTypeName(typeAdr); + break; + case ikProcedure: //0x15 + result = "__fastcall (*" + RTTIName + ")"; + //MethSig + procSig = *((DWORD*)(Code + pos)); pos += 4; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + //Procedure Signature + if (procSig) + { + if (IsValidImageAdr(procSig)) + pos = Adr2Pos(procSig); + else + pos = _ap + procSig; + //Flags + flags = Code[pos]; pos++; + if (flags != 0xFF) + { + //CallConv + callConv = Code[pos]; pos++; + //ResultType + resultTypeAdr = *((DWORD*)(Code + pos)); pos += 4; + result += "("; + //ParamCount + paramCount = Code[pos]; pos++; + for (i = 0; i < paramCount; i++) + { + if (i) result += " ,"; + //Flags + paramFlags = Code[pos]; pos++; + //ParamType + typeAdr = *((DWORD*)(Code + pos)); pos += 4; + //Name + len = Code[pos]; pos++; + name = String((char*)(Code + pos), len); pos += len; + typname = GetTypeName(typeAdr); + typeKind = GetTypeKind(typname, &size); + if (typeKind == ikRecord || typeKind == ikVMT) + result += "struct "; + result += SanitizeName(typname); + if (typeKind == ikVMT) + result += "*"; + if (paramFlags & 1) result += "*"; + result += " " + name; + //AttrData + dw = *((WORD*)(Code + pos)); + pos += dw;//ATR!! + } + result += ")"; + + if (resultTypeAdr) + { + typname = GetTypeName(resultTypeAdr); + typeKind = GetTypeKind(typname, &size); + if (typeKind == ikRecord || typeKind == ikVMT) + result = "struct " + SanitizeName(typname) + "* " + result; + else + result = SanitizeName(typname) + " " + result; + } + else + result = "void " + result; + } + } + break; + case ikVMT: + fieldsList = new TList; + fieldsNum = FMain_11011981->LoadAllFields(adr, fieldsList); + //Add fields from Interface Table + intfList = new TStringList; + intfNum = FMain_11011981->LoadIntfTable(adr, intfList); + prevOfs = -1; + for (m = 0; m < intfNum; m++) + { + //item has format "ADDRESS OFFSET GUID" + item = intfList->Strings[m]; + //pos points to OFFSET + item = item.SubString(item.Pos(' ') + 1, 4); + curOfs = StrToInt("$" + item); + //Check repeated fields + if (prevOfs == -1 || prevOfs != curOfs) + { + fInfo = new FIELDINFO; + fInfo->Name = "Interface_table"; + fInfo->Offset = curOfs; + fInfo->Type = "IInterface"; + fieldsList->Add((void*)fInfo); + prevOfs = curOfs; + } + } + + fieldsList->Sort(FieldsCmpFunction); + //struct begins from pointer to vmt + result += "struct " + RTTIName + "_vmt* v;\n"; + curOfs = 4; + for (m = 0; m < fieldsList->Count; m++) + { + fInfo = (PFIELDINFO)fieldsList->Items[m]; + elOff = fInfo->Offset; + //Skip big offsets (who knows about it's appearence, for example in TComponent) + if (elOff > GetClassSize(adr)) + break; + + //Check long types like double, that has two referenced parts (or records and so on) + if (elOff < curOfs) + continue; + + if (elOff > curOfs) + { + result += "BYTE gap" + Val2Str0(curOfs) + "[0x" + Val2Str0(elOff - curOfs) + "];\n"; + curOfs = elOff; + } + + if (fInfo->Type != "?" && fInfo->Type != "") + { + typeKind = GetTypeKind(fInfo->Type, &size); + if (typeKind == ikEnumeration) size = 1; + if (typeKind == ikMethod) size = 8; + if (typeKind == ikInterface) size = 4; + if (typeKind == ikRecord || typeKind == ikVMT) + result += "struct "; + result += SanitizeName(fInfo->Type); + if (typeKind == ikVMT) + result += "*"; + } + else + { + size = 1; + result += "BYTE"; + } + result += " f" + Val2Str0(fInfo->Offset); + if (fInfo->Name != "") + result += "_" + fInfo->Name; + result += ";\n"; + + curOfs += size; + } + size = GetClassSize(adr); + if (curOfs < size) + result += "BYTE gap" + Val2Str0(curOfs) + "[0x" + Val2Str0(size - curOfs) + "];\n"; + + fieldsList->Clear(); + delete fieldsList; + intfList->Clear(); + delete intfList; + break; + } + return result; +} +//--------------------------------------------------------------------------- diff --git a/Sources/Forms/TypeInfo2.dfm b/TypeInfo.dfm similarity index 85% rename from Sources/Forms/TypeInfo2.dfm rename to TypeInfo.dfm index 587e442..06a9b12 100644 --- a/Sources/Forms/TypeInfo2.dfm +++ b/TypeInfo.dfm @@ -1,8 +1,8 @@ object FTypeInfo_11011981: TFTypeInfo_11011981 Left = 267 Top = 331 - ClientHeight = 395 - ClientWidth = 684 + Width = 700 + Height = 434 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -20,7 +20,7 @@ object FTypeInfo_11011981: TFTypeInfo_11011981 Left = 0 Top = 0 Width = 684 - Height = 362 + Height = 363 Align = alClient Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -31,17 +31,15 @@ object FTypeInfo_11011981: TFTypeInfo_11011981 ReadOnly = True ScrollBars = ssVertical TabOrder = 0 - ExplicitHeight = 363 end object Panel1: TPanel Left = 0 - Top = 362 + Top = 363 Width = 684 Height = 33 Align = alBottom TabOrder = 1 Visible = False - ExplicitTop = 363 object bSave: TButton Left = 251 Top = 7 diff --git a/TypeInfo.h b/TypeInfo.h new file mode 100644 index 0000000..e3de6c5 --- /dev/null +++ b/TypeInfo.h @@ -0,0 +1,38 @@ +//--------------------------------------------------------------------------- +#ifndef TypeInfoH +#define TypeInfoH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include "KnowledgeBase.h" +#include +//--------------------------------------------------------------------------- +String __fastcall Guid2String(BYTE* Guid); +//--------------------------------------------------------------------------- +class TFTypeInfo_11011981 : public TForm +{ +__published: // IDE-managed Components + TMemo *memDescription; + TPanel *Panel1; + TButton *bSave; + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall bSaveClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); +private: // User declarations + int RTTIKind; + DWORD RTTIAdr; + String RTTIName; +public: // User declarations + __fastcall TFTypeInfo_11011981(TComponent* Owner); + void __fastcall ShowKbInfo(MTypeInfo* tInfo); + String __fastcall GetRTTI(DWORD adr); + String __fastcall GetCppTypeInfo(DWORD adr, int* size, int action); + void __fastcall ShowRTTI(DWORD adr); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFTypeInfo_11011981 *FTypeInfo_11011981; +//--------------------------------------------------------------------------- +#endif diff --git a/UFileDropper.cpp b/UFileDropper.cpp new file mode 100644 index 0000000..a7a494a --- /dev/null +++ b/UFileDropper.cpp @@ -0,0 +1,52 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "UFileDropper.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +//--------------------------------------------------------------------------- +TDragDropHelper::TDragDropHelper(const HWND h) + :wndHandle(h) +{ + ::DragAcceptFiles(wndHandle, true); +} +//--------------------------------------------------------------------------- +TDragDropHelper::~TDragDropHelper() +{ + ::DragAcceptFiles(wndHandle, false); +} +//--------------------------------------------------------------------------- +__fastcall TFileDropper::TFileDropper(HDROP aDropHandle) + :DropHandle(aDropHandle) +{ +} +//--------------------------------------------------------------------------- +__fastcall TFileDropper::~TFileDropper() +{ + ::DragFinish(DropHandle); +} +//--------------------------------------------------------------------------- +String TFileDropper::GetFile(int Index) +{ + const int FileNameLength = ::DragQueryFile(DropHandle, Index, 0, 0); + + String res; + res.SetLength(FileNameLength); + ::DragQueryFile(DropHandle, Index, res.c_str(), FileNameLength + 1); + + return res; +} +//--------------------------------------------------------------------------- +int TFileDropper::GetFileCount() +{ + return ::DragQueryFile(DropHandle, 0xFFFFFFFF, 0, 0); +} +//--------------------------------------------------------------------------- +TPoint TFileDropper::GetPoint() +{ + TPoint res(0,0); + DragQueryPoint(DropHandle, &res); + return res; +} +//--------------------------------------------------------------------------- diff --git a/UFileDropper.h b/UFileDropper.h new file mode 100644 index 0000000..a5f23cb --- /dev/null +++ b/UFileDropper.h @@ -0,0 +1,41 @@ +//--------------------------------------------------------------------------- +#ifndef UFileDropperH +#define UFileDropperH + +#include + +// +//simple class that allow/disallow drag-drop support for window +// +class TDragDropHelper +{ +public: + TDragDropHelper(const HWND); + ~TDragDropHelper(); +private: + const HWND wndHandle; +}; + +// +//simple class that accepts dropped files and stores names + droppoint +// +class TFileDropper : public TObject +{ +public: + __fastcall TFileDropper(HDROP ); + virtual __fastcall ~TFileDropper(); + + __property int FileCount = {read=GetFileCount}; + __property String Files[int Index] = {read=GetFile}; + __property TPoint DropPoint = {read=GetPoint}; + +private: + HDROP DropHandle; + String GetFile(int Index); + int GetFileCount(); + TPoint GetPoint(); +}; + +//--------------------------------------------------------------------------- +#endif + diff --git a/UfrmFormTree.cpp b/UfrmFormTree.cpp new file mode 100644 index 0000000..2ef8366 --- /dev/null +++ b/UfrmFormTree.cpp @@ -0,0 +1,362 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "UfrmFormTree.h" +#include "Main.h" +#include "Misc.h" +#include +#include +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//--------------------------------------------------------------------------- +//as: todo: refactor! extern linkage is bad practice (idea: use singleton) +extern TResourceInfo *ResInfo; +extern PInfoRec *Infos; +extern DWORD CodeBase; +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::AddEventsToNode(String compName, TTreeNode* dstNode, TList* evList) +{ + const int evCnt = evList->Count; + for (int m = 0; m < evCnt; m++) + { + EventListItem *item = (EventListItem*)evList->Items[m]; + if (SameText(item->CompName, compName)) + { + tvForm->Items->AddChildObject(dstNode, MakeNodeEventCaption(item), (void*)item->Adr); + } + } +} +//--------------------------------------------------------------------------- +__fastcall TIdrDfmFormTree_11011981::TIdrDfmFormTree_11011981(TComponent* Owner) + : TForm(Owner) +{ + ThinkCursor waitCursor; + + TForm* frmOwner = (TForm*)Owner; + + const int compCnt = frmOwner->ComponentCount; + if (compCnt > 1) + Caption = frmOwner->Name + " (" + String(compCnt) + " components)"; + else + Caption = frmOwner->Name + " (1 component)"; + + std::auto_ptr evList(new TList); + ResInfo->GetEventsList(frmOwner->Name, evList.get()); + + tvForm->Items->BeginUpdate(); + + TTreeNode* rootNode = tvForm->Items->AddObject(0, frmOwner->Name, frmOwner); + AddTreeNodeWithTag(rootNode, frmOwner); + AddEventsToNode(frmOwner->Name, rootNode, evList.get()); + + TComponent* currComp; + TControl* currControl; + TTreeNode *parentNode, *childNode; + bool externalParent = false; + String externalNames; + + for (int i = 0; i < compCnt; i++) + { + currComp = frmOwner->Components[i]; + if (currComp == this) continue; //Don't display Form TreeView + + String tnCaption = MakeNodeCaption(currComp); + + TComponent* parCompo = currComp->GetParentComponent(); + + if (currComp->HasParent()) + { + //in some very rare cases parent could be located in another module! + //so in this case we have true for currComp->HasParent() but NULL for parCompo + if (!parCompo) + { + externalParent = true; + + if (!externalNames.IsEmpty()) + externalNames += ", "; + externalNames += tnCaption; + } + + String parName = parCompo ? parCompo->Name : String("N/A"); + String ownName = currComp->Owner->Name; + + parentNode = FindTreeNodeByTag(parCompo); + + //tricky case for special components (eg: TPage, TTabPage) + //they are a) noname (but renamed in IDR) + // b) not present in Components[] array + + if (!parentNode && parCompo) + { + TComponent* parCompo2 = parCompo->GetParentComponent(); + String parName2 = parCompo2->Name; + TTreeNode *parentNode2 = FindTreeNodeByTag(parCompo2); + + // add noname parent + parentNode = tvForm->Items->AddChildObject(parentNode2, MakeNodeCaption(parCompo), parCompo); + AddTreeNodeWithTag(parentNode, parCompo); + } + } + else + parentNode = FindTreeNodeByTag(currComp->Owner); + + childNode = tvForm->Items->AddChildObject(parentNode, tnCaption, currComp); + AddTreeNodeWithTag(childNode, currComp); + AddEventsToNode(currComp->Name, childNode, evList.get()); + } + + rootNode->Expand(false); + tvForm->Items->EndUpdate(); + + if (externalParent) + { + Application->MessageBox(("Form has some component classes defined in external modules:\r\n" + + externalNames + ".\r\n\r\nVisualization of these components is not yet implemented").c_str(), "Warning", MB_OK | MB_ICONWARNING); + } +} +//--------------------------------------------------------------------------- +String TIdrDfmFormTree_11011981::MakeNodeCaption(TComponent* curCompo) +{ + String className = curCompo->ClassName(); + + IdrDfmDefaultControl* replControl; + if ((replControl = dynamic_cast(curCompo))!=0) + className = "!" + replControl->GetOrigClassName(); + + return curCompo->Name + ":" + className; + + //as: old code + //return curCompo->Name + ":" + curCompo->ClassName(); +} +//--------------------------------------------------------------------------- +String TIdrDfmFormTree_11011981::MakeNodeEventCaption(void* item) +{ + if (((EventListItem*)item)->Adr) + { + PInfoRec recN = GetInfoRec(((EventListItem*)item)->Adr); + if (recN && recN->HasName()) + return ((EventListItem*)item)->EventName + "=" + recN->GetName(); + } + return ((EventListItem*)item)->EventName; +} +//--------------------------------------------------------------------------- +TTreeNode* __fastcall TIdrDfmFormTree_11011981::FindTreeNodeByTag(const void* tag) +{ + TTreeNodeMap::const_iterator it = NodesMap.find(tag); + if (it != NodesMap.end()) return it->second; + + return 0; +} + +//--------------------------------------------------------------------------- +TTreeNode* __fastcall TIdrDfmFormTree_11011981::FindTreeNodeByText(TTreeNode* nodeFrom, const String& txt, bool caseSensitive) +{ + TTreeNode* tn = 0; + bool startScan = nodeFrom ? false : true; + + + TTreeNodes* nodes = tvForm->Items; + for (int i=0; i < nodes->Count; ++i) + { + if (!startScan) + { + if (nodeFrom == nodes->Item[i]) + startScan = true; + continue; + } + + String ttt = nodes->Item[i]->Text; + if ((caseSensitive && AnsiContainsStr(nodes->Item[i]->Text, txt)) + || (!caseSensitive && AnsiContainsText(nodes->Item[i]->Text, txt)) + ) + { + tn = nodes->Item[i]; + break; + } + } + + return tn; +} + +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::AddTreeNodeWithTag(TTreeNode* node, const void* tag) +{ + NodesMap[tag] = node; +} +//--------------------------------------------------------------------------- +bool __fastcall TIdrDfmFormTree_11011981::IsEventNode(TTreeNode* selNode) +{ + return (selNode && !selNode->Text.IsEmpty() && selNode->Text.Pos("=")); +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::FormKeyDown(TObject *Sender, + WORD &Key, TShiftState Shift) +{ + if (VK_ESCAPE == Key) + { + Key = 0; + Close(); + ((TForm*)Owner)->SetFocus(); + } + else if (VK_F3 == Key) + { + dlgFindFind(Sender); + } + else if (Shift.Contains(ssCtrl) + && 'F' == Key + ) + { + dlgFind->Execute(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::tvFormKeyPress(TObject *Sender, char &Key) +{ + if (VK_RETURN == Key) + { + Key = 0; + tvFormDblClick(Sender); + } +} +//--------------------------------------------------------------------------- +void TIdrDfmFormTree_11011981::BorderTheControl(TControl* aControl) +{ + std::auto_ptr C(new TControlCanvas()); + TWinControl* parCtrl = aControl->Parent; + + if (!parCtrl) parCtrl = (TWinControl*)aControl; + + HDC aDC; + TRect aRect; + HWND aHandle; + bool bMenu; + + C->Control = parCtrl; + + aHandle = parCtrl->Handle; + aDC = GetWindowDC(aHandle); + C->Handle = aDC; + C->Brush->Style = bsSolid; + C->Pen->Width = 1; + C->Pen->Color = clRed; + + aRect = aControl->ClientRect; + TForm* frm = dynamic_cast(parCtrl); + bMenu = frm && frm->Menu != 0; + AdjustWindowRectEx(&aRect, + GetWindowLong(aHandle, GWL_STYLE), + bMenu, + GetWindowLong(aHandle, GWL_EXSTYLE)); + MoveWindowOrg(aDC, -aRect.Left, -aRect.Top); + + if (parCtrl == aControl) + { + aRect = aControl->ClientRect; + } + else + { + aRect = aControl->BoundsRect; + InflateRect(&aRect, 2, 2); + } + //C->Rectangle(aRect); + C->DrawFocusRect(aRect); + + ReleaseDC(aHandle, aDC); +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::tvFormDblClick(TObject *Sender) +{ + TTreeNode* selNode = tvForm->Selected; + if (!selNode) return; + + if (IsEventNode(selNode)) + { + const DWORD Adr = (const DWORD)selNode->Data; + if (Adr && IsValidCodeAdr(Adr)) + { + PInfoRec recN = GetInfoRec(Adr); + if (recN) + { + if (recN->kind == ikVMT) + FMain_11011981->ShowClassViewer(Adr); + else + FMain_11011981->ShowCode(Adr, 0, -1, -1); + } + } + return; + } + + TControl* selControl = dynamic_cast((TComponent*)selNode->Data); + if (!selControl) return; + + TWinControl* parControl = selControl->Parent; + if (!parControl) return; + + TForm* ownerForm = (TForm*)Owner; + + ownerForm->BringToFront(); + selControl->BringToFront(); + + for (int i = 0; i < 2; i++) + { + BorderTheControl(selControl); + selControl->Hide(); + selControl->Update(); + Sleep(150); + BorderTheControl(selControl); + selControl->Show(); + selControl->Update(); + Sleep(150); + } + + BringToFront(); +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::dlgFindFind(TObject *Sender) +{ + bool caseSensitive = dlgFind->Options.Contains(frMatchCase); + + TTreeNode* tn = FindTreeNodeByText(tvForm->Selected, dlgFind->FindText, caseSensitive); + if (!tn) + tn = FindTreeNodeByText(0, dlgFind->FindText.Trim(), caseSensitive); + + if (tn) + { + tvForm->Selected = tn; + tn->Expand(false); + tvForm->SetFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::Expand1Click(TObject *Sender) +{ + if (tvForm->Selected) + tvForm->Selected->Expand(true); +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::Collapse1Click(TObject *Sender) +{ + if (tvForm->Selected) + tvForm->Selected->Collapse(false); +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::Find1Click(TObject *Sender) +{ + dlgFind->Execute(); +} +//--------------------------------------------------------------------------- + +void __fastcall TIdrDfmFormTree_11011981::FormClose(TObject *Sender, + TCloseAction &Action) +{ + dlgFind->CloseDialog(); +} +//--------------------------------------------------------------------------- +void __fastcall TIdrDfmFormTree_11011981::FormCreate(TObject *Sender) +{ + ScaleForm(this); +} +//--------------------------------------------------------------------------- + diff --git a/Sources/Forms/UfrmFormTree.dfm b/UfrmFormTree.dfm similarity index 90% rename from Sources/Forms/UfrmFormTree.dfm rename to UfrmFormTree.dfm index 417aa7e..bfeeb97 100644 --- a/Sources/Forms/UfrmFormTree.dfm +++ b/UfrmFormTree.dfm @@ -1,10 +1,10 @@ object IdrDfmFormTree_11011981: TIdrDfmFormTree_11011981 Left = 638 Top = 371 + Width = 331 + Height = 465 BorderStyle = bsSizeToolWin Caption = 'frmDfmTree' - ClientHeight = 426 - ClientWidth = 315 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -22,8 +22,8 @@ object IdrDfmFormTree_11011981: TIdrDfmFormTree_11011981 object tvForm: TTreeView Left = 0 Top = 0 - Width = 315 - Height = 426 + Width = 323 + Height = 425 Align = alClient Font.Charset = RUSSIAN_CHARSET Font.Color = clWindowText diff --git a/UfrmFormTree.h b/UfrmFormTree.h new file mode 100644 index 0000000..179b77a --- /dev/null +++ b/UfrmFormTree.h @@ -0,0 +1,76 @@ +//--------------------------------------------------------------------------- +#ifndef UfrmFormTreeH +#define UfrmFormTreeH +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +//#include +//#include +//#include +//#include +//#include +#include + +typedef std::map TTreeNodeMap; +//--------------------------------------------------------------------------- +class TIdrDfmFormTree_11011981 : public TForm +{ +__published: // IDE-managed Components + TTreeView *tvForm; + TFindDialog *dlgFind; + TPopupMenu *mnuTree; + TMenuItem *Expand1; + TMenuItem *Collapse1; + TMenuItem *Find1; + void __fastcall tvFormKeyPress(TObject *Sender, char &Key); + void __fastcall tvFormDblClick(TObject *Sender); + void __fastcall dlgFindFind(TObject *Sender); + void __fastcall Expand1Click(TObject *Sender); + void __fastcall Collapse1Click(TObject *Sender); + void __fastcall Find1Click(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall FormCreate(TObject *Sender); +private: // User declarations + String MakeNodeCaption(TComponent* curCompo); + String MakeNodeEventCaption(void* item); + void BorderTheControl(TControl* aControl); + + void __fastcall AddEventsToNode(String compName, TTreeNode* dstNode, TList* evList); + TTreeNode* __fastcall FindTreeNodeByText(TTreeNode* nodeFrom, const String& txt, bool caseSensitive); + TTreeNode* __fastcall FindTreeNodeByTag(const void* tag); + void __fastcall AddTreeNodeWithTag(TTreeNode* node, const void* tag); + TTreeNodeMap NodesMap; + + bool __fastcall IsEventNode(TTreeNode* selNode); +public: // User declarations + __fastcall TIdrDfmFormTree_11011981(TComponent* Owner); +}; + +//--------------------------------------------------------------------------- +//show thinking cursor (ctor - show, dtor - hide with restore previous) + +class ThinkCursor +{ +public: + inline ThinkCursor() + { + prevCursor = Screen->Cursor; + Screen->Cursor = crHourGlass; + Application->ProcessMessages(); + } + inline ~ThinkCursor() + { + Screen->Cursor = prevCursor; + } + +private: + Controls::TCursor prevCursor; +}; + +//--------------------------------------------------------------------------- +#endif diff --git a/Bins/.gitignore b/bin/.gitignore similarity index 100% rename from Bins/.gitignore rename to bin/.gitignore diff --git a/bin/Icons.dll b/bin/Icons.dll new file mode 100644 index 0000000..ac58347 Binary files /dev/null and b/bin/Icons.dll differ diff --git a/bin/Idr.exe b/bin/Idr.exe new file mode 100644 index 0000000..3ae2d1e Binary files /dev/null and b/bin/Idr.exe differ diff --git a/Dll/dis.dll b/bin/dis.dll similarity index 100% rename from Dll/dis.dll rename to bin/dis.dll diff --git a/dis.dll b/dis.dll new file mode 100644 index 0000000..f2a3ae0 Binary files /dev/null and b/dis.dll differ diff --git a/idr.chm b/idr.chm new file mode 100644 index 0000000..1cfb771 Binary files /dev/null and b/idr.chm differ diff --git a/Images/idr.ico b/idr.ico similarity index 100% rename from Images/idr.ico rename to idr.ico diff --git a/idr.manifest b/idr.manifest new file mode 100644 index 0000000..5050111 --- /dev/null +++ b/idr.manifest @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + true + + + \ No newline at end of file diff --git a/Images/idr.png b/idr.png similarity index 100% rename from Images/idr.png rename to idr.png diff --git a/idr_manifest.res b/idr_manifest.res new file mode 100644 index 0000000..a49de49 Binary files /dev/null and b/idr_manifest.res differ diff --git a/kb2.7z b/kb2.7z new file mode 100644 index 0000000..9066430 Binary files /dev/null and b/kb2.7z differ diff --git a/kb2005.7z b/kb2005.7z new file mode 100644 index 0000000..8a7afd9 Binary files /dev/null and b/kb2005.7z differ diff --git a/kb2006.7z b/kb2006.7z new file mode 100644 index 0000000..a0f7cbc Binary files /dev/null and b/kb2006.7z differ diff --git a/kb2007.7z b/kb2007.7z new file mode 100644 index 0000000..9d5a094 Binary files /dev/null and b/kb2007.7z differ diff --git a/kb2009.7z b/kb2009.7z new file mode 100644 index 0000000..8fc3853 Binary files /dev/null and b/kb2009.7z differ diff --git a/kb2010.7z b/kb2010.7z new file mode 100644 index 0000000..e951917 Binary files /dev/null and b/kb2010.7z differ diff --git a/kb2011.7z b/kb2011.7z new file mode 100644 index 0000000..675acf5 Binary files /dev/null and b/kb2011.7z differ diff --git a/kb2012.7z b/kb2012.7z new file mode 100644 index 0000000..2f14409 Binary files /dev/null and b/kb2012.7z differ diff --git a/kb2013.7z b/kb2013.7z new file mode 100644 index 0000000..50c9b17 Binary files /dev/null and b/kb2013.7z differ diff --git a/kb2014.7z b/kb2014.7z new file mode 100644 index 0000000..29a367c Binary files /dev/null and b/kb2014.7z differ diff --git a/kb3.7z b/kb3.7z new file mode 100644 index 0000000..20ec3a2 Binary files /dev/null and b/kb3.7z differ diff --git a/kb4.7z b/kb4.7z new file mode 100644 index 0000000..7f6d0d0 Binary files /dev/null and b/kb4.7z differ diff --git a/kb5.7z b/kb5.7z new file mode 100644 index 0000000..cb03982 Binary files /dev/null and b/kb5.7z differ diff --git a/kb6.7z b/kb6.7z new file mode 100644 index 0000000..c392d28 Binary files /dev/null and b/kb6.7z differ diff --git a/kb7.7z b/kb7.7z new file mode 100644 index 0000000..0b3b4f4 Binary files /dev/null and b/kb7.7z differ diff --git a/manifest.rc b/manifest.rc new file mode 100644 index 0000000..637641e --- /dev/null +++ b/manifest.rc @@ -0,0 +1,3 @@ +#define MANIFEST 24 +#define IDR_MANIFEST 1 +IDR_MANIFEST MANIFEST "idr.manifest" \ No newline at end of file diff --git a/Win32/.gitignore b/obj/.gitignore similarity index 100% rename from Win32/.gitignore rename to obj/.gitignore diff --git a/Images/spezkota.jpg b/spezkota.jpg similarity index 100% rename from Images/spezkota.jpg rename to spezkota.jpg diff --git a/syskb2.bin b/syskb2.bin new file mode 100644 index 0000000..6a91732 Binary files /dev/null and b/syskb2.bin differ diff --git a/syskb2005.bin b/syskb2005.bin new file mode 100644 index 0000000..b3394dd Binary files /dev/null and b/syskb2005.bin differ diff --git a/syskb2006.bin b/syskb2006.bin new file mode 100644 index 0000000..112281c Binary files /dev/null and b/syskb2006.bin differ diff --git a/syskb2007.bin b/syskb2007.bin new file mode 100644 index 0000000..6a4d295 Binary files /dev/null and b/syskb2007.bin differ diff --git a/syskb2009.bin b/syskb2009.bin new file mode 100644 index 0000000..e5291df Binary files /dev/null and b/syskb2009.bin differ diff --git a/syskb2010.bin b/syskb2010.bin new file mode 100644 index 0000000..b8f6379 Binary files /dev/null and b/syskb2010.bin differ diff --git a/syskb2011.bin b/syskb2011.bin new file mode 100644 index 0000000..8624949 Binary files /dev/null and b/syskb2011.bin differ diff --git a/syskb2012.bin b/syskb2012.bin new file mode 100644 index 0000000..519b7a5 Binary files /dev/null and b/syskb2012.bin differ diff --git a/syskb2013.bin b/syskb2013.bin new file mode 100644 index 0000000..c32df78 Binary files /dev/null and b/syskb2013.bin differ diff --git a/syskb2014.bin b/syskb2014.bin new file mode 100644 index 0000000..06e3306 Binary files /dev/null and b/syskb2014.bin differ diff --git a/syskb3.bin b/syskb3.bin new file mode 100644 index 0000000..6e350d4 Binary files /dev/null and b/syskb3.bin differ diff --git a/syskb4.bin b/syskb4.bin new file mode 100644 index 0000000..2b73b31 Binary files /dev/null and b/syskb4.bin differ diff --git a/syskb5.bin b/syskb5.bin new file mode 100644 index 0000000..352814e Binary files /dev/null and b/syskb5.bin differ diff --git a/syskb6.bin b/syskb6.bin new file mode 100644 index 0000000..0de4241 Binary files /dev/null and b/syskb6.bin differ diff --git a/syskb7.bin b/syskb7.bin new file mode 100644 index 0000000..4803194 Binary files /dev/null and b/syskb7.bin differ