我这里有一段来自反编译器 Ghidra 的代码。 它用于将一些加密的二进制文件解码为 html(纯文本)。 我想知道该函数是如何工作的以及它使用的解码算法是什么(如果不是自定义解码)。
我很确定这是解码函数,因为当调试器运行此函数时,它会在内存转储中显示解码后的 html。 (我已经命名了一些变量,我不是专家,也许有些变量是错误的)
那么,这个解码器是如何工作的? 我进行了一些研究,发现这可能与 chiper 有关?
void CRYPT_decrypt_content(uint *rawdata,uint *decrypted,uint *param_3)
{
byte rawData_B3_RShift8;
ulonglong PROCED_single_rawData_B2;
ulonglong PROCED_single_rawData_B3;
ulonglong PROCED_single_rawData_B1;
ulonglong PROCED_single_rawData_B0;
uint *shifted8_R8_reg;
int i;
byte rawData_B3_RShift16;
uint PROCED_multi_1;
uint PROCED_multi_2;
uint PROCED_multi_3;
uint rawData_B0;
uint rawData_B1;
uint rawData_B2;
uint rawData_B3;
/* Sub Rawdata into Diff Var
Use key or some data in R8 Register to calculate decryption */
rawData_B3 = rawdata[3];
rawData_B2 = rawdata[2];
rawData_B1 = rawdata[1];
rawData_B0 = *rawdata;
PROCED_single_rawData_B3 =
((ulonglong)(rawData_B3 >> 8 | rawData_B3 << 24) & 0xff00ff00 |
(ulonglong)((rawData_B3 & 0xff00) << 8 | rawData_B3 >> 24)) ^ (ulonglong)param_3[3];
PROCED_single_rawData_B2 =
((ulonglong)(rawData_B2 >> 8 | rawData_B2 << 24) & 0xff00ff00 |
(ulonglong)((rawData_B2 & 0xff00) << 8 | rawData_B2 >> 24)) ^ (ulonglong)param_3[2];
PROCED_single_rawData_B1 =
((ulonglong)(rawData_B1 >> 8 | rawData_B1 << 24) & 0xff00ff00 |
(ulonglong)((rawData_B1 & 0xff00) << 8 | rawData_B1 >> 24)) ^ (ulonglong)param_3[1];
PROCED_single_rawData_B0 =
((ulonglong)(rawData_B0 >> 8 | rawData_B0 << 24) & 0xff00ff00 |
(ulonglong)((rawData_B0 & 0xff00) << 8 | rawData_B0 >> 0x18)) ^ (ulonglong)*param_3;
/* Re set RawData block to new Processed data + some algorithm */
rawData_B3 = *(uint *)(&DAT_180008aa0 + (PROCED_single_rawData_B3 >> 16 & 255) * 4) ^
*(uint *)(&DAT_1800086a0 + (PROCED_single_rawData_B2 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (PROCED_single_rawData_B0 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + (PROCED_single_rawData_B1 & 0xff) * 4) ^ param_3[4];
rawData_B0 = *(uint *)(&DAT_1800086a0 + (PROCED_single_rawData_B3 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + (PROCED_single_rawData_B0 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (PROCED_single_rawData_B1 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + (PROCED_single_rawData_B2 & 0xff) * 4) ^ param_3[5];
shifted8_R8_reg = param_3 + 8;
rawData_B2 = *(uint *)(&DAT_1800086a0 + (PROCED_single_rawData_B0 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + (PROCED_single_rawData_B1 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (PROCED_single_rawData_B2 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + (PROCED_single_rawData_B3 & 0xff) * 4) ^ param_3[6];
i = (int)param_3[60] >> 1;
rawData_B1 = *(uint *)(&DAT_1800086a0 + (PROCED_single_rawData_B1 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + (PROCED_single_rawData_B2 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (PROCED_single_rawData_B3 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + (PROCED_single_rawData_B0 & 0xff) * 4) ^ param_3[7];
while( true ) {
i = i + -1;
rawData_B3_RShift8 = (byte)(rawData_B3 >> 8);
rawData_B3_RShift16 = (byte)(rawData_B3 >> 16);
/* Infinitly execute until BREAK kw */
if (i == 0) break;
PROCED_multi_1 =
*(uint *)(&DAT_1800086a0 + ((ulonglong)(rawData_B0 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + ((ulonglong)(rawData_B2 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(rawData_B1 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + (ulonglong)(rawData_B3 & 0xff) * 4) ^ shifted8_R8_reg[3];
PROCED_multi_2 =
*(uint *)(&DAT_1800086a0 + (ulonglong)rawData_B3_RShift8 * 4) ^
*(uint *)(&DAT_180008aa0 + ((ulonglong)(rawData_B0 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(rawData_B2 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)rawData_B1 & 0xff) * 4) ^ shifted8_R8_reg[2];
PROCED_multi_3 =
*(uint *)(&DAT_180008aa0 + (ulonglong)rawData_B3_RShift16 * 4) ^
*(uint *)(&DAT_1800086a0 + ((ulonglong)(rawData_B1 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(rawData_B0 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)rawData_B2 & 0xff) * 4) ^ shifted8_R8_reg[1];
rawData_B1 = *(uint *)(&DAT_1800086a0 + ((ulonglong)(rawData_B2 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + ((ulonglong)(rawData_B1 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(rawData_B3 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)rawData_B0 & 0xff) * 4) ^ *shifted8_R8_reg ;
/* rawData_b1 Act as PROCED_multi_4 */
rawData_B3 = *(uint *)(&DAT_1800086a0 + ((ulonglong)(PROCED_multi_2 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + ((ulonglong)(PROCED_multi_1 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(rawData_B1 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)PROCED_multi_3 & 0xff) * 4) ^
shifted8_R8_reg[4];
rawData_B0 = *(uint *)(&DAT_180008aa0 + ((ulonglong)(rawData_B1 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_1800086a0 + ((ulonglong)(PROCED_multi_1 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(PROCED_multi_3 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)PROCED_multi_2 & 0xff) * 4) ^
shifted8_R8_reg[5];
rawData_B2 = *(uint *)(&DAT_1800086a0 + ((ulonglong)(rawData_B1 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + ((ulonglong)(PROCED_multi_3 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(PROCED_multi_2 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)PROCED_multi_1 & 0xff) * 4) ^
shifted8_R8_reg[6];
rawData_B1 = *(uint *)(&DAT_1800086a0 + ((ulonglong)(PROCED_multi_3 >> 8) & 0xff) * 4) ^
*(uint *)(&DAT_180008aa0 + ((ulonglong)(PROCED_multi_2 >> 0x10) & 0xff) * 4) ^
*(uint *)(&DAT_180008fa0 + (ulonglong)(PROCED_multi_1 >> 0x18) * 4) ^
*(uint *)(&DAT_180009fd0 + ((ulonglong)rawData_B1 & 0xff) * 4) ^ shifted8_R8_reg[ 7]
;
/* Shift PTR by 8 */
shifted8_R8_reg = shifted8_R8_reg + 8;
}
/* while true jne Here Above */
PROCED_multi_1 =
CONCAT31(CONCAT21(CONCAT11((&DAT_180008ea0)[rawData_B3 >> 0x18],
(&DAT_180008ea0)[(ulonglong)(rawData_B1 >> 0x10) & 0xff]),
(&DAT_180008ea0)[(ulonglong)(rawData_B2 >> 8) & 0xff]),
(&DAT_180008ea0)[(ulonglong)rawData_B0 & 0xff]) ^ *shifted8_R8_reg;
*decrypted = PROCED_multi_1 >> 8 & 0xff00ff00 | PROCED_multi_1 << 0x18 |
(PROCED_multi_1 & 0xff00) << 8 | PROCED_multi_1 >> 0x18;
PROCED_multi_1 =
CONCAT31(CONCAT21(CONCAT11((&DAT_180008ea0)[rawData_B0 >> 0x18],
(&DAT_180008ea0)[rawData_B3_RShift16]),
(&DAT_180008ea0)[(ulonglong)(rawData_B1 >> 8) & 0xff]),
(&DAT_180008ea0)[(ulonglong)rawData_B2 & 0xff]) ^ shifted8_R8_reg[1];
decrypted[1] = PROCED_multi_1 >> 8 & 0xff00ff00 | PROCED_multi_1 << 0x18 |
(PROCED_multi_1 & 0xff00) << 8 | PROCED_multi_1 >> 0x18;
PROCED_multi_1 =
CONCAT31(CONCAT21(CONCAT11((&DAT_180008ea0)[rawData_B2 >> 0x18],
(&DAT_180008ea0)[(ulonglong)(rawData_B0 >> 0x10) & 0xff]),
(&DAT_180008ea0)[rawData_B3_RShift8]),
(&DAT_180008ea0)[(ulonglong)rawData_B1 & 0xff]) ^ shifted8_R8_reg[2];
decrypted[2] = PROCED_multi_1 >> 8 & 0xff00ff00 | PROCED_multi_1 << 0x18 |
(PROCED_multi_1 & 0xff00) << 8 | PROCED_multi_1 >> 0x18;
rawData_B3 = CONCAT31(CONCAT21(CONCAT11((&DAT_180008ea0)[rawData_B1 >> 0x18],
(&DAT_180008ea0)[(ulonglong)(rawData_B2 >> 0x10) & 0xff] ),
(&DAT_180008ea0)[(ulonglong)(rawData_B0 >> 8) & 0xff]),
(&DAT_180008ea0)[rawData_B3 & 0xff]) ^ shifted8_R8_reg[3];
decrypted[3] = rawData_B3 >> 8 & 0xff00ff00 | rawData_B3 << 0x18 |
(rawData_B3 & 0xff00) << 8 | rawData_B3 >> 0x18;
return;
}
这是这个函数的调用者
decrypted_memaddrPTR = (uint *)operator_new((longlong)(filesize + 16));
CRYPT_decrypt_content(EncryptedRawData,decrypted_memaddrPTR,Decryption_key);
if (0x10 < filesize) {
lVar5 = (longlong)decrypted_memaddrPTR - (longlong)EncryptedRawData;
i._0_4_ = (filesize - 17U >> 4) + 1;
i = (ulonglong)(uint)i;
do {
/* shift pointer to new block of data */
EncryptedRawData = EncryptedRawData + 4;
CRYPT_decrypt_content
(EncryptedRawData,(uint *)(lVar5 + (longlong)EncryptedRawData),Decryption_key);
i = i - 1;
} while (i != 0);
}
目前我的理解如下, EncryptedRawData 是原始数据内存地址的 PTR。 解密的_memaddrPTR是解码数据存储的位置(内存地址)。 Decryption_key(我认为)是指向密钥在内存中位置的指针。
如果你们需要更多信息,如果我能找到它,我会回复
注意:调用者位于从该 dll 导出的另一个函数中,并在另一个应用程序的 dotnet 中用作外部函数!