Detect-It-Easy/db/PE/Delphi.4.sg
2024-11-12 20:11:38 +03:00

270 lines
No EOL
10 KiB
JavaScript

// Detect It Easy: detection rule file
// 1995-2007 Borland Delphi
// 2007-2014 Embarcadero Delphi;
// https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Compiler_Versions
// coauthor: sendersu
init("compiler", "Borland Delphi");
includeScript("Borland");
function getVersion() {
if (PE.isNET()) {
if (PE.isNetObjectPresent("Borland.Vcl.Types")) {
sVersion = "8";
} else if (PE.isNetObjectPresent("Borland.Eco.Interfaces")) {
sVersion = "8 Eco WinForm";
} else if (PE.isNetObjectPresent("Borland.Delphi.System") &&
PE.isNetObjectPresent("WinForm")) {
sVersion = "8 WinForm";
} else if (PE.isNetObjectPresent("Borland.Delphi.Units")) {
sVersion = "2005 for .NET";
} else if (PE.isNetObjectPresent("Borland.Studio.Delphi")) {
sName = "Embarcadero Delphi";
sVersion = "XE*";
sOptions = ".NET";
} else {
return 0;
}
return 1;
}
var nSectionOffset = PE.section[0].FileOffset,
nSectionSize = PE.section[0].FileSize,
nOffset = nSectionOffset,
nSize = nSectionSize,
nOffset2,
nAddress,
nLng,
nLng1,
bNewVersion = 0;
var nAddressSize = PE.isPEPlus() ? 8 : 4;
while (nSize > 0) {
nOffset = PE.findSignature(nOffset, nSize, "0708'TControl'");
if (nOffset == -1) {
break;
}
nAddress = PE.readDword(nOffset + 10);
nOffset2 = PE.VAToOffset(nAddress);
if (nOffset2 != -1) {
if ((nOffset2 >= nSectionOffset) && (nOffset2 < nSectionOffset + nSectionSize)) {
nLng = PE.readDword(nOffset2 - 10 * nAddressSize);
nLng1 = PE.readDword(nOffset2 - 10 * nAddressSize - 11 * nAddressSize);
switch (nLng) {
case 0:
if (nLng1 == 0x746E4907) {
sVersion = "3";
} else if (nLng1 == 0x4F540774) {
sVersion = "2";
}
break;
case 0x0B4:
sVersion = "C++ Builder";
break;
case 0x114:
sVersion = "4";
break;
case 0x120:
sVersion = "5";
break;
case 0x128:
sVersion = "6 CLX";
break;
case 0x12C:
sVersion = "7 CLX";
break;
case 0x138:
sVersion = "Kylix";
break;
case 0x15C:
case 0x160:
sVersion = (nLng1 == 0x40100000 || nLng1 == 0x100000) ? "7" : "6";
break;
case 0x164:
sVersion = "2005";
break;
case 0x190:
sVersion = "2006";
break;
default:
nLng = PE.readDword(nOffset2 - 13 * nAddressSize);
if (nLng == 0x1A4) {
sName = "Embarcadero Delphi";
sVersion = "2009";
} else if (nLng == 0x1AC) {
if (PE.resource["PACKAGEINFO"]) {
nOffset = PE.resource["PACKAGEINFO"].Offset;
nSize = PE.resource["PACKAGEINFO"].Size;
if (PE.isSignaturePresent(nOffset, nSize, "'ExcUtils'")) {
sName = "Embarcadero Delphi";
sVersion = "XE";
} else if (PE.isSignaturePresent(nOffset, nSize, "'StrUtils'")) {
sName = "Embarcadero Delphi";
sVersion = "2010";
} else {
sName = "Embarcadero Delphi";
sVersion = "2010 or XE";
}
}
} else if (nLng == 0x1B4) {
// 32
sName = "Embarcadero Delphi";
sVersion = "XE2-XE4";
} else if ((nLng == 0x2F0) || (nLng == 0x2F8)) {
// 64
sName = "Embarcadero Delphi";
sVersion = "XE2";
} else if (nLng == 0x1BC) {
// 32
sName = "Embarcadero Delphi";
sVersion = "XE5-XE6";
bNewVersion = 1;
} else {
if (nAddressSize == 8) {
nLng = PE.readDword(nOffset2 - 16 * nAddressSize);
if (nLng == 0x2F8) {
// 64
sName = "Embarcadero Delphi";
sVersion = "XE3-X4";
} else if (nLng == 0x308) {
// 64
sName = "Embarcadero Delphi";
sVersion = "XE5-XE6";
bNewVersion = 1;
}
}
}
}
if ((sVersion != "") && (!bNewVersion)) {
return 1;
}
}
}
nOffset++;
nSize = nSectionSize - (nOffset - nSectionOffset + 1);
}
if (PE.resource["PACKAGEINFO"]) {
nOffset = PE.resource["PACKAGEINFO"].Offset;
nSize = PE.resource["PACKAGEINFO"].Size;
if (PE.isSignaturePresent(nOffset, nSize, "'System.SysUtils'")) {
sName = "Embarcadero Delphi";
sVersion = "XE2-XE6";
bNewVersion = 1;
} else if (PE.isSignaturePresent(nOffset, nSize, "'ExcUtils'")) {
sName = "Embarcadero Delphi";
sVersion = "XE";
} else if (PE.isSignaturePresent(nOffset, nSize, "'StrUtils'")) {
sName = "Embarcadero Delphi";
sVersion = "2009-2010";
} else if (PE.isSignaturePresent(nOffset, nSize, "'ImageHlp'")) {
sVersion = "2006";
} else if (PE.isSignaturePresent(nOffset, nSize, "'SysInit'")) {
sVersion = "6-7 or 2005";
}
if ((sVersion != "") && (!bNewVersion)) {
return 1;
}
} else {
if (PE.findString(PE.section[0].FileOffset, PE.section[0].FileSize, "Borland\\Delphi") != -1) {
sVersion = "2-3";
return 1;
}
}
if (bNewVersion) {
if (PE.section[".rdata"]) {
var nRDataOffset = PE.section[".rdata"].FileOffset;
var nRDataSize = PE.section[".rdata"].FileSize;
var nVersionOffset = PE.findString(nRDataOffset, nRDataSize, "Embarcadero Delphi for Win");
if (nVersionOffset != -1) {
var sCompilerVersion = PE.getString(nVersionOffset + 46, 4);
if (sCompilerVersion == "28.0") {
sVersion = "XE7";
} else if (sCompilerVersion == "29.0") {
sVersion = "XE8";
} else if (sCompilerVersion == "30.0") {
sVersion = "10 Seattle";
} else if (sCompilerVersion == "31.0") {
sVersion = "10.1 Berlin";
} else if (sCompilerVersion == "32.0") {
sVersion = "10.2 Tokyo";
} else if (sCompilerVersion == "33.0") {
sVersion = "10.3 Rio";
} else if (sCompilerVersion == "34.0") {
sVersion = "10.4 Sydney";
} else if (sCompilerVersion == "35.0") {
sVersion = "11.0 Alexandria";
} else if (sCompilerVersion == "36.0") {
sVersion = "12.0 Athens";
} else {
sVersion = "12.x Athens++";
}
}
}
return 1;
}
return 0;
}
function detect() {
if (bBorlandC) { // can't be Delphi if it's already C/C++
return null;
}
if (PE.resource["PACKAGEINFO"]) {
bDetected = true;
getVersion();
}
if (PE.resource["DVCLAL"]) {
bDetected = true;
getVersion();
// try to decode DVCLAL (Delphi Visual Component Library Access License) values
nOffset = PE.getResourceNameOffset("DVCLAL");
if (PE.compare("A28CDF987B3C3A7926713F090F2A2517", nOffset)) {
sOptions = "Professional";
} else if (PE.compare("23785D23B6A5F31943F3400226D111C7", nOffset)) {
sOptions = "Standard";
} else if (PE.compare("263D4F38C28237B8F3244203179B3A83", nOffset)) {
sOptions = "Enterprise";
}
} else if (PE.resource["TMAINFORM"]) {
bDetected = true;
getVersion();
} else if (PE.isNET()) {
if (getVersion()) {
bDetected = true;
}
} else if (PE.compare("0A06'string'", PE.section[0].FileOffset)) {
sVersion = "2";
bDetected = true;
} else if (PE.findSignature(PE.section[0].FileOffset, 100, "07'Boolean'") != -1) {
bDetected = true;
getVersion();
} else if (PE.findSignature(PE.section[0].FileOffset, 100, "06'String'") != -1) {
bDetected = true;
getVersion();
} else if (PE.findSignature(PE.section[0].FileOffset, 0x100, "FF25........8BC0FF25........8BC0")) {
if (getVersion()) {
bDetected = true;
}
}
_setLang("Object Pascal (Delphi)", bDetected);
return result();
}