#1
|
|||
|
|||
WinCE dll unpacking
Hi,
I have a packed dll for WinCE and I wan't to analyse it. Unfortunately I can not identify what protector is used. It seems that the dll is unpack himself in the memory during runtime. There is only 5 functions who does the unpacking/decompressing, so I decide to make a static unpacker for it. I have a problem to analyse 2 short functions, and I don't know how to handle them: Quote:
Quote:
Maybe somebody can give me some tips how to handle this calls? Regards, leader |
#2
|
|||
|
|||
Hi,
I have a problem with the analyze one function. I think this function make the decompression of the code in the memory. It has many integer overflow checks and it will be overflow in short time: Code:
char *__fastcall sub_9F92(char *a1, int a2, _BYTE *a3, _DWORD *a4) { char *v4; // r7 unsigned int v5; // r5 int v6; // r4 char *result; // r0 char v8; // r3 unsigned __int8 v9; // cf int i; // r1 int v11; // r1 unsigned __int8 v12; // cf unsigned __int8 v13; // cf int v14; // r4 unsigned int v15; // r1 unsigned __int8 v16; // cf int v17; // r3 signed int v18; // r1 int v19; // r5 int v20; // r5 unsigned __int8 v21; // cf unsigned __int8 v22; // cf unsigned __int8 v23; // cf int v24; // r4 unsigned __int8 v25; // cf int v26; // r1 unsigned __int8 v27; // cf int v28; // r3 _BYTE *v29; // [sp+0h] [bp-1Ch] _DWORD *v30; // [sp+4h] [bp-18h] v29 = a3; v30 = a4; v4 = &a1[a2]; v5 = -1; v6 = 0x80000000; while ( 1 ) { v9 = __CFADD__(v6, v6); v6 *= 2; if ( !v6 ) return a1 + 1; if ( !v9 ) { for ( i = 1; ; i = v11 + v12 + v11 ) { v13 = __CFADD__(v6, v6); v14 = 2 * v6; if ( !v14 ) return a1 + 1; v15 = i + v13 + i; v16 = __CFADD__(v14, v14); v6 = 2 * v14; if ( !v6 ) return a1 + 1; if ( v16 ) break; v11 = v15 - 1; v12 = __CFADD__(v6, v6); v6 *= 2; if ( !v6 ) return a1 + 1; } v9 = v15 >= 3; v17 = v15 - 3; v18 = 0; if ( v9 ) { v19 = (unsigned __int8)*a1++; v20 = ~(v19 | (v17 << 8)); if ( !v20 ) { result = (char *)(a1 - v4); *v30 = a3 - v29; return result; } v9 = v20 & 1; v5 = v20 >> 1; if ( !v9 ) { LABEL_21: v18 = 1; v22 = __CFADD__(v6, v6); v6 *= 2; if ( !v6 ) return a1 + 1; if ( !v22 ) { while ( 1 ) { v23 = __CFADD__(v6, v6); v24 = 2 * v6; if ( !v24 ) break; v18 += v23 + v18; v25 = __CFADD__(v24, v24); v6 = 2 * v24; if ( !v6 ) break; if ( v25 ) { v26 = v18 + 4; goto LABEL_30; } } return a1 + 1; } } } else { v21 = __CFADD__(v6, v6); v6 *= 2; if ( !v6 ) return a1 + 1; if ( !v21 ) goto LABEL_21; } v27 = __CFADD__(v6, v6); v6 *= 2; if ( !v6 ) return a1 + 1; v26 = v18 + v27 + v18 + 2; LABEL_30: if ( v5 < 0xFFFFFB00 ) ++v26; v28 = (unsigned __int8)*a3; do { *a3 = a3[v5]; ++a3; --v26; } while ( v26 ); continue; } v8 = *a1++; *a3++ = v8; } } - a1 => compressed code buffer - a2 => length of compressed code buffer - a3 => To this address will be decompressed the the code - a4 => I think it will store the lengh of decompressed code (not sure) __CFADD__ check if the sum of 2 integers is overflow or not. Tipically used to check the sum of the same integer. There is another overflow check by multiply the integer with 2 (For example v6 *= 2) As you see the inital value of integer v6 is 0x80000000, so it produce very fast overflow and the function will return without decompressing the code. I try to reproduce this ARM code on X86 but without success. I spent many time on it, but I can not understand the purpose of this overflow checks and how the decompression made. I would be very pleased with all your useful ideas. Thanks, leader Last edited by leader; 01-20-2018 at 02:32. Reason: Put formated code into CODE section instead of QUOTE... |
#3
|
|||
|
|||
I just identified that the function above is NRV2E decription rutine.
It is used in UPX, so I think this windows ce dll is compressed with a modified UPX. I made a little program to decompress code section using UCL library, now I need to rebuild import library.... |
Tags |
wince dll unpack |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
WinCE Floating-Point operators - HELP | leader | General Discussion | 0 | 01-31-2018 03:18 |