#1
|
|||
|
|||
Need help identifying modified blowfish algo
Hello,
i am working on an arm linux elf file that has blowfish encryption algorithm inside. But whatever i did to reproduce them, i can't get the same results. this is what it's like in decompiled form. Code:
unsigned int __fastcall CBlowFish::Encode(CBlowFish *this, unsigned __int8 *a2, unsigned __int8 *a3, unsigned int a4) { v4 = a3; v26 = a2; v23 = a4; v25 = this; v5 = CBlowFish::GetOutputLength(this, a4); v6 = v5; if ( v5 ) { v7 = 0; v8 = v23; v9 = (unsigned int *)v4; v10 = (unsigned int *)v26; v24 = v23 - 7; v22 = v5 - v23; do { if ( v26 == v4 ) { if ( v7 >= v24 ) { v11 = (char *)v10 + v23; if ( v22 > 0 ) { v12 = (int)&v11[v22]; do *v11++ = 0; while ( v11 != (_BYTE *)v12 ); } } v13 = v10; v14 = v10 + 1; v10 += 2; CBlowFish::Blowfish_encipher(v25, v13, v14); goto LABEL_9; } if ( v7 >= v24 ) { v17 = v8; if ( v8 <= 0 ) { v21 = (int)v9; v17 = 0; } else { v18 = 0; do { *((_BYTE *)v9 + v18) = *((_BYTE *)v10 + v18); ++v18; } while ( v8 != v18 ); v21 = (int)v9 + v8; v10 = (unsigned int *)((char *)v10 + v8); if ( v8 > 7 ) goto LABEL_14; } v19 = v21 - v17; v20 = v17; do *(_BYTE *)(v19 + v20++) = 0; while ( v20 <= 7 ); } else { v16 = 0; do { *((_BYTE *)v9 + v16) = *((_BYTE *)v10 + v16); ++v16; } while ( v16 != 8 ); } LABEL_14: v10 += 2; CBlowFish::Blowfish_encipher(v25, v9, v9 + 1); v9 += 2; LABEL_9: v7 += 8; v8 -= 8; } while ( v6 > v7 ); } return v6; Code:
int __fastcall CBlowFish::Blowfish_encipher(CBlowFish *this, unsigned int *a2, unsigned int *a3) v3 = *(_DWORD **)this; v4 = *((_DWORD *)this + 1); v5 = *a2 ^ **(_DWORD **)this; v6 = *(_DWORD *)(*(_DWORD *)this + 20); v7 = *a3 ^ (((*(_DWORD *)(v4 + 4 * ((v5 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v5 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v5 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v5 + 3072)) ^ *(_DWORD *)(*(_DWORD *)this + 4); v8 = *(_DWORD *)(*(_DWORD *)this + 24); v9 = v5 ^ (((*(_DWORD *)(v4 + 4 * ((v7 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v7 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v7 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v7 + 3072)); v10 = *(_DWORD *)(*(_DWORD *)this + 32); v11 = v9 ^ *(_DWORD *)(*(_DWORD *)this + 8); v12 = *(_DWORD *)(*(_DWORD *)this + 28); v13 = *(_DWORD *)(*(_DWORD *)this + 36); v14 = *(_DWORD *)(*(_DWORD *)this + 40); v15 = *(_DWORD *)(*(_DWORD *)this + 44); v16 = (((*(_DWORD *)(v4 + 4 * ((v11 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v11 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v11 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v11 + 3072)) ^ *(_DWORD *)(*(_DWORD *)this + 12) ^ v7; v17 = v3[17]; v18 = (((*(_DWORD *)(v4 + 4 * ((v16 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v16 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v16 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v16 + 3072)) ^ v3[4] ^ v11; v19 = v3[16]; v20 = (((*(_DWORD *)(v4 + 4 * ((v18 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v18 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v18 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v18 + 3072)) ^ v6 ^ v16; v21 = (((*(_DWORD *)(v4 + 4 * ((v20 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v20 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v20 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v20 + 3072)) ^ v8 ^ v18; v22 = (((*(_DWORD *)(v4 + 4 * ((v21 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v21 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v21 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v21 + 3072)) ^ v12 ^ v20; v23 = (((*(_DWORD *)(v4 + 4 * ((v22 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v22 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v22 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v22 + 3072)) ^ v10 ^ v21; v24 = (((*(_DWORD *)(v4 + 4 * ((v23 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v23 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v23 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v23 + 3072)) ^ v13 ^ v22; v25 = (((*(_DWORD *)(v4 + 4 * ((v24 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v24 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v24 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v24 + 3072)) ^ v14 ^ v23; v26 = (((*(_DWORD *)(v4 + 4 * ((v25 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v25 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v25 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v25 + 3072)) ^ v15 ^ v24; v27 = (((*(_DWORD *)(v4 + 4 * ((v26 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v26 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v26 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v26 + 3072)) ^ v3[12] ^ v25; v28 = (((*(_DWORD *)(v4 + 4 * ((v27 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v27 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v27 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v27 + 3072)) ^ v3[13] ^ v26; v29 = (((*(_DWORD *)(v4 + 4 * ((v28 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v28 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v28 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v28 + 3072)) ^ v3[14] ^ v27; v30 = (((*(_DWORD *)(v4 + 4 * ((v29 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v29 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v29 >> 8) + 2048)) + *(_DWORD *)(v4 + 4 * (unsigned __int8)v29 + 3072)) ^ v3[15] ^ v28; v31 = v4 + 4 * ((unsigned __int16)v30 >> 8); v32 = *(_DWORD *)(v4 + 4 * (v30 >> 24)); v33 = v4 + 4 * (unsigned __int8)v30; v34 = *(_DWORD *)(v4 + 4 * ((v30 >> 16) & 0xFF) + 1024); result = v30 ^ v17; *a3 = (((v34 + v32) ^ *(_DWORD *)(v31 + 2048)) + *(_DWORD *)(v33 + 3072)) ^ v19 ^ v29; *a2 = result; return result; hxxps://filebin.net/yordbkvlpmofbaem thanks in advance |
#2
|
|||
|
|||
upper function std::string *__fastcall linx::LCEncryption::EncryptDecrypt(std::string *pStrOutput, const char **ppInput, int mode)
Code:
v7 = lenInput % 8; if ( lenInput % 8 ) v7 = 8 - v7; lSize = lenInput + v7; v9 = lenInput + v7 + 1; pInput = operator new[](v9); memset(pInput, 0, v9); strcpy(pInput, *ppInput); CBlowFish::CBlowFish(); BYTE key[2] = {0}; CBlowFish::Initialize(key, 2);//??? if (mode) { pOutput = operator new[](2 * lSize); memset(pOutput, 0, 2 * lSize); CBlowFish::Encode(pInput, pOutput, lSize); bits = (8 * lSize); lenBase32Str = linx::LCBase32::toLen(bits); Base32Str = operator new[](lenBase32Str); memset(Base32Str, 0, lenBase32Str); linx::LCBase32::toBaseStr(Base32Str, lenBase32Str, pOutput, bits); v24 = strlen(Base32Str); std::string::assign(pStrOutput, Base32Str, v24); } Maybe if you can show some sample pairs of input/output strings to LCEncryption::EncryptDecrypt I don't have the proper arm env to debug the exe, tried it in qemu but it cries for missing so libs and some (QT) are compiled for this embedded app (ie not something that can be googled for) maybe if you can make a rootfs of the env or don't know, do a find / -name \*.so and only pack those (you have at least read access because of the a binary) Last edited by ionioni; 10-06-2020 at 21:04. |
#3
|
|||
|
|||
i am new in reversing arm binaries. but, i don't think running that big elf file would be any use. or maybe qemu has debug capability?
been trying to setup qemu as ida debugger but it just hangs at start up. and there's really little information about this (ida and qemu) in the web. Quote:
Quote:
1824781686.png Quote:
thanks Last edited by dion; 10-06-2020 at 21:47. |
#4
|
|||
|
|||
Quote:
Last edited by ionioni; 10-07-2020 at 03:01. |
#5
|
|||
|
|||
Quote:
Try Azeria Labs VM https://azeria-labs.com/arm-lab-vm/ https://azeria-labs.com/lab-vm-2-0/ https://azeria-labs.com/emulating-arm-firmware/ Or Hugsy (the creator of GEF) VM labs https://blahcat.github.io/2017/06/25/qemu-images-to-play-with/ |
Thread Tools | |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Identifying compiler version from .NET binary | jonwil | General Discussion | 2 | 06-25-2020 03:15 |
Identifying licenses / users from packed executables | Notmex | General Discussion | 6 | 12-07-2013 03:32 |
Blowfish encryption | lonewolf55 | General Discussion | 2 | 09-18-2003 02:08 |