diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2020-05-24 16:48:22 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2020-05-25 21:57:14 +0200 |
commit | 31c69b6ca1b91e7fd9fd8e14082fd2584c5f538c (patch) | |
tree | 16e789c7d68608831b498f41f54d9482b82a711a /source/decrypter_x86.asm |
first public release
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'source/decrypter_x86.asm')
-rw-r--r-- | source/decrypter_x86.asm | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/source/decrypter_x86.asm b/source/decrypter_x86.asm new file mode 100644 index 0000000..b3a04ec --- /dev/null +++ b/source/decrypter_x86.asm @@ -0,0 +1,101 @@ +; Module: decrypter_x86.asm +; Author: Toni <matzeton@googlemail.com> +; Purpose: 1. decrypt a buffer encrypted with xor32npcbc + +%ifndef _LDR_SECTION +%error "expected _LDR_SECTION to be defined" +%endif +SECTION _LDR_SECTION +GLOBAL __decrypt_x86 + +EBP_BUFF EQU 0x08 +EBP_SIZE EQU 0x0c +EBP_IVPT EQU 0x10 +EBP_KEYP EQU 0x14 +EBP_IVKY EQU 0x18 + +; xor32n_pcbc decryption routine +; arguments: [ebp + 0x08] = buffer_ptr32 +; [ebp + 0x0c] = size_u32 +; [ebp + 0x10] = iv_ptr32 +; [ebp + 0x14] = key_ptr32 +; [ebp + 0x18] = ivkeysize +; modifies : eax, ebx, ecx, edx, esi, edi +; return : eax = FALSE if error, non-zero if success +__decrypt_x86: + ; new stack frame + push ebp + mov ebp,esp + ; check if buffer has a valid size + xor edx,edx ; clear remainder + xor ecx,ecx ; clear divisor + mov eax,[ebp + 0x0c] + mov byte cl,0x04 + div ecx ; size_u32 % sizeof(uint32) + xor eax,eax + cmp edx,eax ; remainder == 0 ? + jnz __decrypt_failed + ; uint32_t prev[ivkeysiz]; + mov ecx,[ebp + 0x18] ; ivkeysize + ; calculate and reserve stack space + xor edx,edx + xor eax,eax + mov al,0x04 + mul ecx + sub esp,eax ; make space for ivkeysiz*sizeof(uint32) + ; init prev[i] with iv[i] + mov edx,[ebp + 0x10] ; iv_ptr32 + __decrypt_prev: ; ecx = ivkeysize + mov eax,[ebp + 0x18] ; ivkeysize + sub eax,ecx ; ivkeysize - ecx + mov edi,[edx + eax*4] + mov dword [esp + eax*4],edi + loop __decrypt_prev + ; size_u32 / sizeof(uint32) + mov ecx,[ebp + 0x0c] ; size_u32 + shr ecx,0x02 ; / sizeof(uint32) + ; main decrypt loop + mov edi,ecx ; edi = count + __decrypt_loop: ; ecx = count-i + ; calculate i + mov eax,edi + sub eax,ecx ; count-(count-i) + mov esi,eax ; esi = i + ; calculate iv/key i + xor edx,edx ; clear remainder + mov ebx,[ebp + 0x18] ; ivkeysize + div ebx ; i % ivkeysize + mov ebx,edx ; ebx = iv/key i + ; get buffer content + mov edx,[ebp + 0x08] ; buffer_ptr32 + mov edx,[edx + esi*4] ; edx = buf[i] + ; decrypt content + mov eax,[ebp + 0x14] + mov eax,[eax + ebx*4] ; eax = key[iv/key i] + xor eax,edx ; tmp = xor32_crypt(buf[i], key[iv/key i]) + xor eax,[esp + ebx*4] ; plain = xor32_crypt(tmp, prev[iv/key i]) + push ebx + mov ebx,[ebp + 0x08] ; buffer_ptr32 + mov [ebx + esi*4],eax + pop ebx + ; calculate prev[iv/key i] + xor eax,edx ; prev[iv/key i] = xor32_crypt(plain, crypt) + mov [esp + ebx*4],eax + loop __decrypt_loop + ; cleanup stack + xor edx,edx + xor eax,eax + mov ecx,[ebp + 0x18] + mov al,0x04 + mul ecx + add esp,eax + ; return value (size of buffer) + mov eax,[ebp + 0x0c] + ; restore old frame + pop ebp + ret +__decrypt_failed: + pop ebp + xor eax,eax + ret + |