Electronics > Repair
Help with bricked APC UPS SMT1500
AstroAU:
Just an update of sorts.
UPS from the UK arrived, but it wasn't in an original box but some other thing which was a thin box, the unit had a thin layer of bubble wrap around it and the box was filled with packing peanuts UGH...
The box was not in a good shape and upon inspection the UPS had been dropped and suffered damage to the left rear of the unit.
Using my metal working skills we straightened the bend in the case.
Inserting a new set of batteries that I'd ordered while waiting for the unit to arrive, building the battery pack with connector and fuse (100A) and subsequently powering it up all looked good.
UPS firmware on the sub board was 8.8 and via USB we upgraded that to 15.0 and didn't brick this one :)
It works fine BUT the display goes blank after several days of use. Inserting network card and checking it's configuration. The display is set to permanently ON. So it does have a fault.
Going through Ebay to resolve this but that's another story.
Anyway, The sub board with it's STM32F103RCT6 ARM processor, needs the right piece of hardware to read that. I've got the software for the reader / programmer from this site...
https://stm32-st-link-utility.software.informer.com/
and subsequently ordered also a STM32 reader/programmer that only costs a small amount from Aliexpress.
the UPS IS ID18 so that's a plus. So once I've got that NEW reader on hand then we will read the contents of the sub boards ARM processor.
This sub board is for some basic interfacing to the main UPS board as when I put the working board into the dead UPS, the alarm didn't go off, the display came to life BUT it couldn't control the UPS as it didn't see it.
So once we get this sub board back to life it looks like we WILL need to pull off the AT89C51RC micro controller from the main board of working UPS. Put a socket on the board and read the data from the controller.
Drop in the other controller from the dead UPS and reprogram that and put a socket on that board too and hopefully we will get them both working again.
I do have 44 pin PLCC sockets on hand as well as 8 AT89C51RC micro controllers that came in the post.
Will update in a while when I've got the DATA from the ARM Processor and micro controller for all to use
Looked into the SMT18UPS_15-0.enc file and discovered the extension means it's encrypted and in all things it's a base 64 encryption, so good luck with that :)
So yeah we did look into that as well with no joy.
Photo's of the damage...
DavidAlfa:
.enc might be anything.
flaotte:
--- Quote from: AstroAU on May 05, 2024, 06:57:57 pm --- it's a base 64 encryption, so good luck with that :)
So yeah we did look into that as well with no joy.
--- End quote ---
base64 is just way to transfer binary data over text symbols.
https://en.wikipedia.org/wiki/Base64
there is no key for encryption, you can encode/decode it with any free tool.
AstroAU:
Ahh ok, will look into that further. Thanks flaotte
DavidAlfa:
Definitely not base 64!
The tool is java-based, so much easier to reverse engineer.
You can unpack LaunchFUW.exe with 7zip.
Navigate to com\apc\microlink\fwtool.
Open each class files with in Recaf.
There's some interesting stuff:
DESEncrypter.class
--- Code: ---public class DESEncrypter
implements IEncrypter {
private static final String kENCPREFIX = "SOELM";
private static final String kENCSUFFIX = "EOELM";
private static final String kKEY = "H25s@ase";
public String doEncrypt(String plainText) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
byte[] keyBytes = kKEY.getBytes();
DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
SecretKeyFactory secKeyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = secKeyFactory.generateSecret(desKeySpec);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(1, key);
byte[] textBytes = plainText.getBytes();
String encryptedText = kENCPREFIX + this.byteToHexString(cipher.doFinal(textBytes)) + kENCSUFFIX;
return encryptedText;
}
private String byteToHexString(byte[] byteBlock) {
StringBuilder hexString = new StringBuilder();
int i = 0;
while (i < byteBlock.length) {
byte b = byteBlock[i];
String str = Integer.toHexString(b);
if (str.length() > 2) {
str = str.substring(str.length() - 2);
}
if (str.length() < 2) {
str = "0" + str;
}
hexString.append(str);
++i;
}
return hexString.toString().toUpperCase();
}
}
--- End code ---
FWToolConstants.class
--- Code: --- public static final String kHashPassword = "o9aZNAPyYcxs86ysOpGUdg==";
public static final String kSecretKey = "apcschneider@2021";
--- End code ---
UtilType.class
--- Code: --- private static int deviceID = 0;
String originalString = "apc@123";
private static SecretKeySpec secretKey;
private static byte[] key;
--- End code ---
VerifyFileCompatibility.class
Some stuff going on here, too.
VerifyFileCompatibility$FileHeader.class
Here you can see the firmware file has a 128 byte header, might include a key, keep searching in other class files and you migh find out.
Also there're some details about how to parse the file:
--- Code: --- public void parseData(byte[] data) {
this.version = data[0];
this.command = data[1];
byte[] size = new byte[4];
System.arraycopy(data, 6, size, 0, 4);
this.fileSize = this.unsignedBytesToInt(size);
byte[] id = new byte[2];
System.arraycopy(data, 12, id, 0, 2);
this.deviceID = this.unsignedTwoByteArrayToInt(id);
UtilType.setDevideId((int)this.deviceID);
FWToolApp.theLogger.debugMsg("deviceID:" + this.deviceID);
byte[] filecheck = new byte[2];
System.arraycopy(data, 16, filecheck, 0, 2);
this.fileChecksum = this.unsignedTwoByteArrayToInt(filecheck);
this.index = data[18];
this.fwversionStringSize = data[19];
this.fwversionString = this.setValueFromByteArray(data, this.fwversionStringSize, 20);
FWToolApp.theLogger.debugMsg("fw version String:" + this.fwversionString);
this.byte64 = data[64];
byte[] check = new byte[2];
System.arraycopy(data, 126, check, 0, 2);
this.headerChecksum = this.unsignedTwoByteArrayToInt(check);
byte[] xmodemstring = new byte[33];
System.arraycopy(data, 68, xmodemstring, 0, 33);
this.stringToWaitfor = this.setValueFromByteArray(xmodemstring, 33, 0);
if (this.stringToWaitfor.equals(Messages.getString((String)"VerifyFileCompatibility.45"))) {
this.stringToWaitfor = null;
}
}
--- End code ---
Also: calculatefilechecksum, calculateheaderchecksum.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version