mirror of
https://github.com/horsicq/Detect-It-Easy.git
synced 2026-06-24 01:54:08 +00:00
270 lines
No EOL
10 KiB
JavaScript
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();
|
|
} |